C# ClickOnce不传递第二个Uri

C# ClickOnce不传递第二个Uri,c#,wpf,singleton,clickonce,C#,Wpf,Singleton,Clickonce,我们有一个WPF应用程序,它使用WindowsFormsApplicationBase类使其成为singleton;并使用ClickOne进行部署。每当我们想要执行这个exe时,我们都会通过Uri(服务器中带有查询字符串的部署目录)调用它。所有这些仅适用于此应用程序的第一个实例 问题:无论传递的Uri是什么,每次激活单实例应用程序时,ClickOnce始终传递第一个Uri。此外,不会为同一应用程序的任何后续实例化填充StartupNextInstanceEventArgs 有人有这个问题吗 提前

我们有一个WPF应用程序,它使用
WindowsFormsApplicationBase
类使其成为
singleton
;并使用
ClickOne
进行部署。每当我们想要执行这个exe时,我们都会通过Uri(服务器中带有查询字符串的部署目录)调用它。所有这些仅适用于此应用程序的第一个实例

问题:无论传递的Uri是什么,每次激活单实例应用程序时,ClickOnce始终传递第一个Uri。此外,不会为同一应用程序的任何后续实例化填充
StartupNextInstanceEventArgs

有人有这个问题吗


提前谢谢。

到目前为止,我的问题还没有任何具体的答案。因此,我决定实施前面提到的另一种解决方案。不幸的是,最初的问题在这两种方法中都适用。所以我决定在第二种方法(见url)的基础上做一个变通方法来解决这个问题,直到我有了一个干净的解决方案

解决方法

  • 修改了入口点(Main)以包含将传入激活uri保存到应用程序配置文件的功能。您必须保持这个保存值的位置,因为它倾向于在行的某个地方用旧的激活uri覆盖。记住这是我的问题

     public static void Main()
     {
       string uri;
       StartupHelpers.SetConfigurationValue("ActivationUri", (StartupHelpers.HasTriggeredFromUrl(out uri)) ? uri : string.Empty);    
       if (SingleInstance<App>.InitializeAsFirstInstance(Unique))
            {
             var application = new App();
             application.Run();
             SingleInstance<App>.Cleanup();
            }
     }
    
    publicstaticvoidmain()
    {
    字符串uri;
    SetConfigurationValue(“ActivationUri”,(StartupHelpers.HasTriggeredFromUrl(out uri))?uri:string.Empty);
    if(SingleInstance.InitializeAsFirstInstance(唯一))
    {
    var application=new App();
    application.Run();
    SingleInstance.Cleanup();
    }
    }
    
  • 现在实现接口(ISingleTonistanceApp),如下所示

        public bool SignalExternalCommandLineArgs(IList<string> args)
        {
            var uri = new  Uri(StartupHelpers.GetConfigurationValue("ActivationUri"));
            int queryString = 0;
            if (StartupHelpers.IsTriggeredFromWLink(uri, out queryString))
            {
            //in my case I have a function LoadPage which take 
            //some parameter to populate UI.   Your case might be
            //totally  different. However, the idea is on how we
            //could grab   running instance and pass value into
            // it to do something different.
    
                ((YourMainWindow) (Current.MainWindow)).LoadPage(queryString.ToString());
    
            }
    
            // Bring window to foreground
            if (this.MainWindow.WindowState == WindowState.Minimized)
                {
                this.MainWindow.WindowState = WindowState.Normal;
                }
    
            this.MainWindow.Activate();
    
            return true;
            }
    
    public bool SignalExternalCommandLineArgs(IList args)
    {
    var uri=新uri(StartupHelpers.GetConfigurationValue(“ActivationUri”);
    int queryString=0;
    if(StartupHelpers.IsTriggeredFromWLink(uri,out queryString))
    {
    //在我的例子中,我有一个函数LoadPage,它
    //一些用于填充UI的参数。您的案例可能是
    //完全不同。但是,想法是关于我们如何
    //可以抓取正在运行的实例并将值传递到
    //做一些不同的事情是很有必要的。
    ((YourMainWindow)(Current.MainWindow)).LoadPage(queryString.ToString());
    }
    //将窗口置于前台
    if(this.mainfown.WindowState==WindowState.Minimized)
    {
    this.mainfown.WindowState=WindowState.Normal;
    }
    this.MainWindow.Activate();
    返回true;
    }
    
  • 帮助器获取/设置配置值

        public static class StartupHelpers
    {
          public static bool HasTriggeredFromUrl(out string uri)
           {
            try
            {
                uri = string.Empty;
                var activeUri = ApplicationDeployment.CurrentDeployment.ActivationUri;
                uri = activeUri != null ? activeUri.ToString() : string.Empty;
                return true;
            }
            catch (InvalidDeploymentException inv)
            {
                uri = string.Empty;
                return false;
            }
        }
    
        public static bool IsTriggeredFromLink(Uri activationUri, out int queryStringValue)
        {
            queryStringValue = 0;
            var hasTriggeredFromLink = true;
            if (string.IsNullOrWhiteSpace(activationUri.Query) ||
                HttpUtility.ParseQueryString(activationUri.Query).Count <= 0)
                hasTriggeredFromLink = false;
            else
            {
                if (!int.TryParse(HttpUtility.ParseQueryString(activationUri.Query)[0], out queryStringValue))
                    throw new Exception("Invalid startup argument found from web site.");
    
            }
    
            return hasTriggeredFromLink;
        }
    
        public static bool SetConfigurationValue(string key, string value)
        {
            try
            {
                Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                appConfig.AppSettings.Settings[key].Value = value;
                appConfig.Save(ConfigurationSaveMode.Full);
                ConfigurationManager.RefreshSection("appSettings");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;
        }
    
        public static string GetConfigurationValue(string key)
        {
            try
            {
                Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                ConfigurationManager.RefreshSection("appSettings");
                return appConfig.AppSettings.Settings[key].Value;
    
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
    
    公共静态类StartupHelpers
    {
    公共静态bool HasTriggeredFromUrl(输出字符串uri)
    {
    尝试
    {
    uri=string.Empty;
    var activeUri=ApplicationDeployment.CurrentDeployment.ActivationUri;
    uri=activeUri!=null?activeUri.ToString():string.Empty;
    返回true;
    }
    捕获(InvalidDeploymentException inv)
    {
    uri=string.Empty;
    返回false;
    }
    }
    公共静态bool IsTriggeredFromLink(Uri activationUri,out int queryStringValue)
    {
    queryStringValue=0;
    var hasTriggeredFromLink=true;
    if(string.IsNullOrWhiteSpace(activationUri.Query)||
    
    Count回答有点晚,但我在研究将应用程序强制到单个实例时偶然发现了这一点

    如果我理解您试图执行的操作,那么您需要一个采用命令行参数的单实例应用程序。第二次尝试运行该应用程序时,您只想保留第一个实例,但将第二组命令行参数传递给它

    在这种情况下,为什么不在WPF应用程序中使用适当的方法托管WCF服务,而该方法就是您将这些参数传递给的方法。然后,使用ClickOnce的网页仅使用它将传递的参数调用此服务方法