【问题标题】:Programically get the system name of named pipe以编程方式获取命名管道的系统名称
【发布时间】:2015-02-23 15:32:03
【问题描述】:

我正在使用 WCF NetNamedPipeBinding 编写进程间通信。

我的目标是让服务在“net.pipe://localhost/service”运行,所以我运行最简单的主机:

host = new ServiceHost(contract, new Uri[] { "net.pipe://localhost" });
host.AddServiceEndpoint(typeof (IContract),
    new NetNamedPipeBinding(), "service");
host.Open();

根据http://blogs.msdn.com/b/rodneyviana/archive/2011/03/22/named-pipes-in-wcf-are-named-but-not-by-you-and-how-to-find-the-actual-windows-object-name.aspx 该名称隐藏在系统生成的 guid 后面。

问题来了。

是否有任何可能的方法可以在我的程序中获取系统(guid)生成的名称,所以我可以像在 procexp 中一样获得类似“\Device\NamedPipe\GUID”的路径,这样更容易嗅探它? (除了在单独的进程中运行 sys internals 可执行文件并解析其输出?)

【问题讨论】:

    标签: c# .net wcf wcf-binding named-pipes


    【解决方案1】:

    正如您链接到的文章所示,WCF 将命名管道名称存储在内存映射文件中。要访问它,您需要执行以下操作:

    • 端点:net.pipe://localhost/TradeService/Service1
    • 标准化端点:net.pipe://+/TRADESERVICE/SERVICE1/
    • Base 64 表示:bmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=
    • 最终内存映射文件:net.pipe:EbmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=

    现在您获取最终的 MMF 名称并打开它。这是 MSDN 上关于使用 MMF 的文章:https://msdn.microsoft.com/en-us/library/dd267590(v=vs.110).aspx

    // Open the MMF.
    using (var mmf = MemoryMappedFile.OpenExisting(namedPipeMMFName))
    {
         // Create an accessor for 16 bytes (Size of GUID) starting at 
         // offset 5 (as the article states)
         using (var accessor = mmf.CreateViewAccessor(5, 16))
         {
             Guid pipeGuid;
             accessor.Read<Guid>(0, out pipeGuid);
             Console.WriteLine("This should be the pipe name: " + pipeGuid);
         }
    }
    

    【讨论】:

    • 谢谢。我没想到。此解决方案有效,标记为有效。
    • 这里唯一要做的改变是 mmf.CreateViewAccessor(4, 45)。我尝试了 5,16 并不断得到错误的 guid
    【解决方案2】:

    经过大量的摆弄并将我的头撞在墙上,我终于得到了这个工作:

    Guid pipeGuid;
    if (PipeName.Equals("*", StringComparison.InvariantCultureIgnoreCase) || PipeName.Equals("localhost", StringComparison.InvariantCultureIgnoreCase))
         PipeName = "*";
    
    string s = string.Format(@"net.pipe://{0}/", PipeName.ToUpper());
    
    if(!string.IsNullOrWhiteSpace(ServiceName))
         s = string.Format(@"net.pipe://*/{0}/", ServiceName.ToUpper());
    
    var bytes = Encoding.UTF8.GetBytes(s);
    var base64 = Convert.ToBase64String(bytes);
    
    string namedPipeMMFName = string.Format(@"Global\net.pipe:E{0}", base64);
    
    MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity();
    mSec.AddAccessRule(new AccessRule<MemoryMappedFileRights>(new     SecurityIdentifier(WellKnownSidType.WorldSid, null),  MemoryMappedFileRights.FullControl, AccessControlType.Allow));
    
    using (var mmf = MemoryMappedFile.OpenExisting(namedPipeMMFName, MemoryMappedFileRights.Read))
    {
        using (var accessor = mmf.CreateViewAccessor(4, 45, MemoryMappedFileAccess.Read))
        {
            accessor.Read<Guid>(0, out pipeGuid);
        }
    }
    
    using (NamedPipeClientStream client = new NamedPipeClientStream(GetResolvedText(ServerName), pipeGuid, PipeDirection.InOut,
                            PipeOptions.None, TokenImpersonationLevel.Impersonation))
    {
        client.Connect(10000);
    }
    

    我必须感谢 Rodney Viana 的 his article 和 @Avner Shahar-Kashtan 的回答以及我阅读的许多其他文章。希望我的回答能对以后的人有所帮助。

    【讨论】:

    • 这太棒了——在我看来比公认的答案更好:)..尽管公认的答案确实解释了为什么这样做。
    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2018-09-20
    • 2013-05-31
    • 2012-03-11
    • 1970-01-01
    相关资源
    最近更新 更多