2010-06-18 35 views
6

我目前在.Net中维护一个内部应用程序。应用程序使用IPC一次维护一个运行会话;如果另一个会话尝试打开(某人再次单击该图标,一些会打开一个已保存的结果文件),第二个会话将此信息传达给第一个会话,然后终止,第一个会话将启动请求的操作。如何使用IPC而不是本地管理员?

我目前做这个用的System.ServiceModel命名空间,就像这样:

命名空间EventLogViewer.IPCServer {// 提供的通用框架,流程传达给oneanother。

[ServiceContract(Namespace = "http://ELV.domain")] 
interface IELVLauncher 
{ 
    [OperationContract] 
    bool LaunchTabs(String[] fileNames); 
} 
public delegate void TabLauncher(String[] fileNames); 
class ELVLauncherServer : IDisposable 
{ 
    ServiceHost ipcService; 
    public ELVLauncherServer() 
    { 
     Uri baseAddress = new Uri("Http://localhost:45600/elvlauncher/service"); 
     String address = "net.pipe://localhost/elvlauncher/tablauncher"; 

     ipcService = new ServiceHost(typeof(ELVLauncher), baseAddress); 

     NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); 
     ipcService.AddServiceEndpoint(typeof(IELVLauncher), binding, address); 

     ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 
     behavior.HttpGetEnabled = true; 
     behavior.HttpGetUrl = new Uri("http://localhost:45601/elvlauncher"); 
     ipcService.Description.Behaviors.Add(behavior); 
     Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, "Registering IPC Service")); 
     ipcService.Open(); 

    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     ipcService.Close(); 
    } 

    #endregion 
} 
public class ELVLauncher : IELVLauncher 
{ 
    #region IELVLauncher Members 

    public bool LaunchTabs(string[] fileNames) 
    { 
     try 
     { 
      Utilities.WriteMemoryDebugStatement(new DebugStatement(DebugStatement.StatementType.INFO, String.Format("IPC request received, files: {0}", String.Join(", ", fileNames)))); 
      Program.mainWindow.backgroundListener_OnLaunchRequestReceived(fileNames); 
     } 
     catch (Exception exception) 
     { 
      Utilities.WriteMemoryDebugStatement(new DebugStatement(exception)); 
     } 
     return (true); 
    } 

    #endregion 

} 

此代码最初是在Windows XP下开发的,就像我们大多数公司没有转移到Vista一样。由于我们都以本地管理员身份运行,因此此代码无任何问题。

但是,我们现在正在转换到Win 7,并且此代码在启动时会产生异常,因为它无法注册IPC端点。更多信息在这里:http://mark.michaelis.net/Blog/WindowsCommunicationFoundationWithWindowsVistaAndUAC.aspx

给出的解决方法是将应用程序升级为需要管理员权限。这并不原因有二:

  1. 这个应用程序不需要管理员privledges否则
  2. 我们使用的ClickOnce为我们的内部工具部署和ClickOnce的不支持大于运行的进程启动的任何其他。

所以在这一点上,我需要找到一个不需要管理员权限的IPC解决方案,并让我实现最初的目标:检测已经运行的代码实例并告诉它该做什么,否则启动它自己。任何有关如何做的建议(在.Net框架内,请不要使用第三方解决方案)将不胜感激。

+1

请不要在标题中重复标记“.Net 3.5 C#:”。 – 2010-06-18 18:27:11

回答

3

这是一个难以置信的困难(并且正如您发现的,有问题的方式),以确保您的应用只有一个会话。你应该重构/重做功能use a mutex

这是另一个example. 和必要的wiki article about mutexes

编辑

要解决,你可以生成与OS提供的临时文件夹,其中单个应用程序将查询自己的特殊前缀或扩展名的临时文件通信位(过滤为您的特殊前缀/或扩展名)查看是否提出了更多请求。请参阅:

System.IO.Path.GetTempFileName 

System.IO.Path.GetTempPath 
+0

奖励:可以在没有管理员权限的情况下创建互斥锁。 – Cheeso 2010-06-18 18:01:13

+0

@Cheeso:确切地说。我想我应该在答案中明确说明这一点。 – 2010-06-18 18:02:25

+0

谢谢,但这只能解决一半的问题。第二个过程必须告诉第一个过程要做什么(启动,加载保存的报告)。互斥体不允许这样做。 – Dan 2010-06-18 18:04:03