如何在Windows中获取所有打开的命名管道列表并避免可能的异常?

时间:2014-08-03 21:53:47

标签: c# .net named-pipes

获取命名管道列表在理想情况下非常简单,可以在这里找到: How can I get a list of all open named pipes in Windows?

但提到了解决方案

var namedPipes = Directory.GetFiles(@"\\.\pipe\");

偶尔会出现无法预测的结果。上面的链接中提到了其中一个(路径异常中的无效字符)。今天我遇到了我自己的异常--ArgumentException“第二个路径片段不能是驱动器或UNC名称。参数名称:path2”。

问题是.net中是否有任何真正有用的解决方案来获取所有打开的命名管道的列表?感谢

2 个答案:

答案 0 :(得分:9)

我挖掘了Directory类源代码并找到了灵感。这是一个可行的解决方案,它为您提供所有已打开命名管道的列表。我的结果不包含\\。\ pipe \ prefix,因为它可以在Directory.GetFiles的结果中看到。我在WinXp SP3,Win 7,Win 8.1上测试了我的解决方案。

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct WIN32_FIND_DATA
    {
        public uint dwFileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string cFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);


    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA
       lpFindFileData);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool FindClose(IntPtr hFindFile);

    private static void Main(string[] args)
    {
        var namedPipes = new List<string>();
        WIN32_FIND_DATA lpFindFileData;

        var ptr = FindFirstFile(@"\\.\pipe\*", out lpFindFileData);
        namedPipes.Add(lpFindFileData.cFileName);
        while (FindNextFile(ptr, out lpFindFileData))
        {
            namedPipes.Add(lpFindFileData.cFileName);
        }
        FindClose(ptr);

        namedPipes.Sort();

        foreach (var v in namedPipes)
            Console.WriteLine(v);

        Console.ReadLine();
     }

答案 1 :(得分:0)

使用返回X的.NET 4 API之一,您可以捕获这些异常:

IEnumerable

当然,最后不会列举名称不正确的管道。因此,如果您确实想列出所有所有管道,则不能使用此解决方案。