如何在不成为本地管理员的情况下使用IPC?

Dan*_*Dan 6 c# ipc servicehost .net-3.5

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

我目前使用System.ServiceModel命名空间执行此操作,如下所示:

namespace EventLogViewer.IPCServer {//提供进程与另一个进程通信的通用框架.

[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

}
Run Code Online (Sandbox Code Playgroud)

此代码最初是在Windows XP下开发的,就像我们没有迁移到Vista的大多数公司一样.由于我们都作为本地管理员运行,因此该代码运行没有问题.

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

给出的解决方法是将应用程序设置为需要管理员权限.这不起作用有两个原因:

  1. 此应用程序不需要管理员权限
  2. 我们使用ClickOnce来部署我们的内部工具,ClickOnce不支持除了作为流程启动器运行之外的任何其他工具.

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

Pau*_*sik 3

要确保应用程序的单个会话,这是一种极其困难的方式(正如您所发现的,这是有问题的方式)。您应该重构/重做该功能以使用 mutex

这是另一个例子。 以及有关互斥体的必要wiki 文章

编辑

为了绕过通信位,您可以在操作系统提供的临时文件夹中生成一个带有您自己的特殊前缀和/或扩展名的临时文件,单个应用程序将轮询该临时文件(过滤您的特殊前缀和/或扩展名)以查看是否发出了更多请求。看:

System.IO.Path.GetTempFileName 
Run Code Online (Sandbox Code Playgroud)

System.IO.Path.GetTempPath
Run Code Online (Sandbox Code Playgroud)