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
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();
}
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.