删除命名管道.NET

时间:2013-07-02 10:53:15

标签: .net named-pipes

我正在使用以下代码列出我的命名管道:

    private IEnumerable<string> GetNamedPipesList()
    {
        string[] listOfAllPipes = Directory.GetFiles(@"\\.\pipe\");
        return listOfAllPipes.Where(pipe => pipe.Contains("FST"));
    }

工作正常。我可以显示它们:

    private void Scan_Click(object sender, EventArgs e)
    {
        IEnumerable<string> fsbPipes = GetNamedPipesList();
        tbxOutput.Text = string.Empty;
        foreach (string fsbPipe in fsbPipes)
        {
            var pipe = fsbPipe.Replace(@"\\.\pipe\", "");
            tbxOutput.AppendText(pipe + Environment.NewLine);
        }
    }

示例:

FST-MT4_Miroslav-130
FST-MT4_Miroslav-150
FST-MT4_Miroslav-120

之后我想通过删除类似文件来关闭它们:

    private void CloseAll_Click(object sender, EventArgs e)
    {
        IEnumerable<string> myPipes = GetNamedPipesList();
        foreach (string pipe in myPipes)
        {
            try
            {
                File.Delete(pipe);
            }
            catch (Exception exception)
            {
                tbxOutput.AppendText(exception.Message + Environment.NewLine);
            }
        }
    }

但它返回参数不正确。我不确定我能做到,但我必须尝试,因为我把它们作为文件加载。

如何关闭这些命名管道?

2 个答案:

答案 0 :(得分:3)

根据MSDN,有一组专门用于操作命名管道的类 - 但它们只适用于您在应用程序中实际拥有它们的情况。

您在这里所做的实际上是通过较低的API,文件系统列出命名管道。但是,namedpipes实际上与文件不同:它们通过许多进程共享,并且有一些类似垃圾收集的机制,当它不再使用时会自动删除它们(参见ie http://social.msdn.microsoft.com/Forums/vstudio/en-US/66f747a0-22c9-4e7d-bb5a-e4e63197318a/deleting-named-pipe)。严格来说:当所有感兴趣的进程关闭其管道的句柄时,它将被销毁。

查看用于处理管道的低级API:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365150(v=vs.85).aspx没有提及破坏。仅创建连接断开连接。

如果我没记错的话,即使在* nix文件系统上,命名管道上的'rm'也不会破坏它。它从目录中分离文件的inode并有效地“隐藏”特殊文件,但无论谁打开这个文件 - 保持它并将其固定并且特殊文件仍然存在并且一直在使用,直到最后一个文件句柄关闭,然后才实际文件真的被释放了。

那么..也许你应该尝试改写你的问题并搜索谁拿着烟斗然后“跟他们”以正常的方式关闭手柄?即连接到管道并在正确的应用程序协议中发送礼貌消息“请退出”?

好的,已经写完了所有这些,现在是实际的解决方案。

由于你知道管道,如果你有足够高的访问权限,你可以做任何事情。您可以枚举所有过程,您可以检查它们的手柄,您可以检查每个手柄并检查它指向的是什么。如果它指向管道,您可以提取该管道的名称。如果名称与您的管道匹配,您可以将一个线程注入该进程,并且可以从该线程关闭句柄并立即暂停该进程,以防它检测到损坏的句柄并开始重新连接到该管道。循环遍历所有进程,您可能非常确定您的管道将被关闭。然后,您可以使用现在不存在的管道来执行您的操作并恢复所有这些过程。

我认为所有这一切都是完全可能的,因为像ProcessHacker2这样的工具可以显示其他进程句柄的许多细节,并且还允许您按需关闭该句柄。因此,只需复制,过滤和自动化该任务及其完成。但是,实际上,这是危险的,而且几乎不是稳定/可靠的解决方案。

答案 1 :(得分:3)

感谢@CodeCaster和@quetzalcoatl我发现我们无法删除命名管道,但我们必须杀死他们的持有者。

如果我们知道持有者姓名,最简单的方法就是使用任务管理器。

我制作了一个列出命名管道的小工具。它支持过滤。

下载链接:ListNamedPipes.exe

No filter

Filter Chrome pipes

代码在这里:

    private void Scan_Click(object sender, EventArgs e)
    {
        IEnumerable<string> fsbPipes = GetNamedPipesList();
        tbxOutput.Text = string.Empty;
        foreach (string fsbPipe in fsbPipes)
        {
            string pipe = fsbPipe.Replace(@"\\.\pipe\", "");
            tbxOutput.AppendText(pipe + Environment.NewLine);
        }
    }

    private IEnumerable<string> GetNamedPipesList()
    {
        string[] listOfAllPipes = Directory.GetFiles(@"\\.\pipe\");
        return listOfAllPipes.Where(pipe => pipe.Contains(tbxFilter.Text));
    }