2010-06-18 39 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