Search code examples
c#.netnamed-pipes

How can I get a list of all open named pipes in Windows and avoiding possible exceptions?


Getting the list of named pipes is in ideal case pretty simple and can be found here: How can I get a list of all open named pipes in Windows?

But mentioned solution

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

has occasionally unpredictable results. One of them was mentioned in the link above (Invalid character in path exception). Today I met my own exception:

ArgumentException "The second path fragment must not be a drive or UNC name. Parameter name: path2".

Question is whether there is any really working solution in .net to get the list of all opened named pipes? Thanks


Solution

  • I dug into Directory class source code and found an inspiration. Here is a working solution which gives you list of all opened named pipes. My result does not contain \\.\pipe\ prefix as it can be seen in result of Directory.GetFiles. I tested my solution on 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();
         }