2015-05-26 35 views
1

我们有一个WPF应用程序,它使用WindowsFormsApplicationBase类来使它singleton;并使用ClickOne进行部署。无论何时我们想要执行这个exe文件,我们都会通过Uri调用它(使用查询字符串在服务器中部署的目录)。所有作品都只适用于此应用程序的第一个实例。ClickOnce不通过第二次Uri

问题:ClickOnce在每次启动单实例应用程序时总是传递第一个Uri,而不管传递的是哪个Uri。另外,StartupNextInstanceEventArgs未被填充以用于相同应用程序的任何后续实例化。

有没有人有这个问题?

在此先感谢。

回答

1

到目前为止,我还没有得到任何具体的答案,我的问题。因此,我决定实施一个不同的解决方案,其中提到了here。不幸的是,两种方法都存在原始问题。所以我决定在第二种方法(请参阅url)之上做一个解决方法来解决这个问题,直到我有一个干净的解决方案。

解决方法

  1. 改性入口点(主)为包括功能性,从而节省了输入激活的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(); 
         } 
    } 
    
  2. 现在实现如下的接口(ISingletonInstanceApp)。

    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; 
         } 
    
  3. 帮助获取/设置配置值。

    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; 
         } 
        } 
    } 
    
0

后期答案了一点,但我偶然发现这一点的同时寻找到迫使应用程序的单个实例绊倒。

如果我明白你要做什么,你想要一个单一的实例应用程序,它需要命令行参数。第二次尝试运行应用程序时,您只需保留第一个实例,但将第二组命令行参数传递给它。

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