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

前端 未结 2 1700
温柔的废话
温柔的废话 2021-01-12 22:20

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 solutio

相关标签:
2条回答
  • 2021-01-12 22:26

    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();
         }
    
    0 讨论(0)
  • 2021-01-12 22:41

    Using one of the .NET 4 APIs returning IEnumerable, you can catch those exceptions:

    static IEnumerable<string> EnumeratePipes() {
        bool MoveNextSafe(IEnumerator enumerator) {
    
            // Pipes might have illegal characters in path. Seen one from IAR containing < and >.
            // The FileSystemEnumerable.MoveNext source code indicates that another call to MoveNext will return
            // the next entry.
            // Pose a limit in case the underlying implementation changes somehow. This also means that no more than 10
            // pipes with bad names may occur in sequence.
            const int Retries = 10;
            for (int i = 0; i < Retries; i++) {
                try {
                    return enumerator.MoveNext();
                } catch (ArgumentException) {
                }
            }
            Log.Warn("Pipe enumeration: Retry limit due to bad names reached.");
            return false;
        }
    
        using (var enumerator = Directory.EnumerateFiles(@"\\.\pipe\").GetEnumerator()) {
            while (MoveNextSafe(enumerator)) {
                yield return enumerator.Current;
            }
        }
    }
    

    The badly named pipes are not enumerated in the end, of course. So, you cannot use this solution if you really want to list all of the pipes.

    0 讨论(0)
提交回复
热议问题