System.Diaganostics.Process(当一个进程内部使用另一个进程时)

发布于 2024-08-18 11:03:39 字数 386 浏览 10 评论 0原文

我一直在使用 C# System.Diagnostics.Process 来监视命令行实用程序的输出。

我“内部”监视的进程启动第二个进程,一旦启动,我就不会收到来自进程对象的进一步输出。

令人沮丧的是,如果您使用 cmd.exe(手动)执行相同的命令(我使用 System.Diagnostics.Process 对象启动),控制台会输出我需要在 C# 应用程序中看到的每一行!

但是,如果我(出于测试目的)使用 System.Diagnostics.Process 对象启动 cmd.exe,并运行该命令,它仍然会像之前一样停止输出(直接启动 process1.exe);此时将使用第二个.exe。我以为这个测试会合并所有相关进程的所有输出,但事实并非如此。如何将所有这些输出获取到我的 C# 应用程序中?

I've been using C# System.Diagnostics.Process to monitor the output of a command line utility.

The process I'm monitoring "internally" launches a second process, and as soon as it does, I receive no further output from the process object.

What's frustrating, is, if you execute the very same command (that I'm launching with the System.Diagnostics.Process object) with cmd.exe (manually), the console outputs every line I need to be seeing in my C# app!

However, if I (for testing purposes) launch cmd.exe with the System.Diagnostics.Process object, and run the command, it still stops outputting at the same point that it did previously (launching process1.exe directly); at the point the second.exe is utilised. I thought this test would consolidate all output from all processes involved, but it didn't. How can I get all this output into my C# application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睫毛上残留的泪 2024-08-25 11:03:39

原因是 System.Diagnostics.Process 实际上只监视它所挂接的进程。

避免此问题的一种方法是让您的第一个应用程序在启动第二个应用程序时输出,并且当收到该输出时,从主应用程序监视从(现在是第三个)应用程序创建进程。第三个应用程序启动后,它应该出现在 System.Diagnostics.Process.GetProcesses() 数组中,然后您可以附加到它的 OutputDataReceived 事件。

然后,您的代码将如下所示(未经测试):

private void firstProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (e.Data == "Starting next process")
    {
        System.Diagnostics.Process newProcess = null;

        while (newProcess == null)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process proc in procs)
            {
                if (proc.ProcessName == "newProcess")
                {
                    newProcess = proc;
                    break;
                }
            }

            System.Threading.Thread.Sleep(100);
        }

        newProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(newProcess_OutputDataReceived);
    }
}

void newProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Do something with your data received here.
}

请注意,这只是一个示例,如果您的第三个进程无法启动或结束得太快,则此方法将挂在无限循环中。该示例只是为了向您提供构建适用于您的特定情况的知识,而我对此并不完全熟悉。您至少应该确保 while 循环不会永远持续下去,并且您可能还需要进行一些其他调整。

编辑:或者,如果您无法修改第一个应用程序的源,您可以简单地创建一个新线程,以这种方式(使用 while 循环)不断监视并在单独的类中处理第三个进程的输出,或者只需将第三个进程的输出重新路由到第二个进程的输出的处理程序中,以便您可以使用单个方法处理两个进程的所有输出。

The reason for this is that the System.Diagnostics.Process is literally only monitoring the process to which it is hooked.

One way to circumvent this problem would be for your first application to output when it is starting the second application, and when that output is received, monitor from your main application for the creation of the process from the (now third) application. Once the third application is started, it should appear in the System.Diagnostics.Process.GetProcesses() array, and you can then attach to it's OutputDataReceived event.

Your code would then look something like this (untested):

private void firstProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (e.Data == "Starting next process")
    {
        System.Diagnostics.Process newProcess = null;

        while (newProcess == null)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process proc in procs)
            {
                if (proc.ProcessName == "newProcess")
                {
                    newProcess = proc;
                    break;
                }
            }

            System.Threading.Thread.Sleep(100);
        }

        newProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(newProcess_OutputDataReceived);
    }
}

void newProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Do something with your data received here.
}

Note that this is just a sample, and if your third process fails to start, or ends too quickly, then this method will hang in an infinite loop. This sample is simply meant to provide you with the knowledge to build something that works in your specific case, which I'm not totally familiar with. You should at a very minimum make sure that the while loop will not continue forever, and you'll probably want to make a few other adjustments as well.

EDIT: Alternately, if you can't modify the source to the first application, you could simply create a new thread that monitored in this manner (using the while loop) constantly and handled the output from the third process in a separate class, or simply re-routed the output from the third process into the handler for the output of the second process so that you could have a single method handling all of the output for both processes.

软糖 2024-08-25 11:03:39

您是否需要启动 cmd.exe?难道您不能直接在进程中启动 rsync 进程,然后使用 这个问题来捕获命令执行的输出,以便您可以在代码中使用它们?

Do you need to be launching cmd.exe at all? Can't you just initiate the process for rsync directly in your Process and then use something like the techniques described in this question to catch the output from the command execution so you can work with them in your code?

没︽人懂的悲伤 2024-08-25 11:03:39

我的第一个谷歌搜索是“ProcessDiagnosticInfo.GetForProcesses()”

所以,我转到这个链接:
https://github.com/microsoftarchive/msdn-code-gallery-microsoft/blob/master/OneCodeTeam/How%20to%20get%20information%20of%20running% 20apps%20and%20processes%20in%20UWP%20apps/README.md

并下载 GitHub 文件:
https://github.com/microsoftarchive/msdn-code-gallery-microsoft

在 OneCodeTeam/如何获取 UWP 应用中正在运行的应用和进程的信息
foler,我们可以使用该解决方案。

我已将所有代码复制到我的新项目中,我可以发现类似的症状。

如果您将 Pakage.appxmanifest 作为代码进行研究,您可以发现原始 Github 代码与您的代码之间的差异。

<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windo
ws10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">




<Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="appDiagnostics"/>
</Capabilities>

My first Googling was "ProcessDiagnosticInfo.GetForProcesses()"

So, I go to this link :
https://github.com/microsoftarchive/msdn-code-gallery-microsoft/blob/master/OneCodeTeam/How%20to%20get%20information%20of%20running%20apps%20and%20processes%20in%20UWP%20apps/README.md

And DownLoad the GitHub file :
https://github.com/microsoftarchive/msdn-code-gallery-microsoft

In OneCodeTeam/How to get information of running apps and processes in UWP apps
foler, We can use that solution.

I had copied all codes to my new project and I can found similar symptom.

If you investigate Pakage.appxmanifest as code, you can find difference between original Github code and your code.

<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windo
ws10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">

.
.
.
.

<Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="appDiagnostics"/>
</Capabilities>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文