以编程方式获取命名管道的系统名称

我正在使用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)在我的程序中生成的名称,所以我可以获得像“\ Device \ NamedPipe \ GUID”这样的路径,就像在procexp中一样,所以它会更容易嗅探它? (除了在单独的进程中运行sys internals可执行文件并解析其输出?)

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

  • 端点:net.pipe:// localhost / TradeService / Service1
  • 规范化端点:net.pipe:// + / TRADESERVICE / SERVICE1 /
  • 基数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(0, out pipeGuid); Console.WriteLine("This should be the pipe name: " + pipeGuid); } } 

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

 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(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(0, out pipeGuid); } } using (NamedPipeClientStream client = new NamedPipeClientStream(GetResolvedText(ServerName), pipeGuid, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { client.Connect(10000); } 

我必须感谢罗德尼维亚纳的文章和@Avner Shahar-Kashtan的回答以及我读过的其他许多文章。 我希望我的回答可以帮助将来的某个人。