C#:如何打开进程,等待进程中的程序完全加载,然后使用新进程执行命令?

C#:如何打开进程,等待进程中的程序完全加载,然后使用新进程执行命令?,c#,C#,使用C#,我需要打开一个程序,等待该程序完全加载,然后运行cmd.exe以运行其他命令来操作程序的原始实例 我试图让一个名为GerbView的特定程序以某种方式运行。该程序用于查看Gerber文件,PCB制造商用于蚀刻PCB的文件。这个程序可以用自己的Open命令在内部加载Gerber文件。然而,我的程序是要处理一些Gerber文件,然后使用GerbView加载这些处理过的Gerber文件。我能够完成这项任务的唯一方法是通过命令行界面。可以打开Gerber文件的命令是gerbview{filen

使用C#,我需要打开一个程序,等待该程序完全加载,然后运行cmd.exe以运行其他命令来操作程序的原始实例

我试图让一个名为GerbView的特定程序以某种方式运行。该程序用于查看Gerber文件,PCB制造商用于蚀刻PCB的文件。这个程序可以用自己的Open命令在内部加载Gerber文件。然而,我的程序是要处理一些Gerber文件,然后使用GerbView加载这些处理过的Gerber文件。我能够完成这项任务的唯一方法是通过命令行界面。可以打开Gerber文件的命令是gerbview{filename}

我知道Process类可以通过FileName和Arguments属性轻松完成这项工作,但我需要向同一实例添加更多文件。执行此操作的命令是gerbview/add{filename}

最后一个命令将启动程序,如果一个实例已经打开,它将只添加一个附加文件来查看。这就是我的问题所在。在我提出最终解决方案(见下文)之前,我的程序一直在打开多个实例(尽管使用了/add参数),这可能是因为程序在执行其余的/add参数时没有准备好输入。只有当我添加了1秒延迟时,代码才正确运行。然而,当我向某人展示微软团队时,旧的行为又回来了,直到我增加了延迟(我假设团队广播给出了需要更大延迟的理由)。以下是我当前的解决方案(该程序是windows窗体的一部分):

过程视图;
过程cmd;
bool-gerbViewActive;
//是windows窗体构造函数
公共WindowsFormGUI()
{
初始化组件();
gerbViewActive=false;
}
私有无效按钮取消程序\单击(对象发送者,事件参数e)
{
OpenFileDialog loadFiles=新建OpenFileDialog
{
Multiselect=true,
InitialDirectory=Directory.GetParent(Directory.GetCurrentDirectory()).FullName
};
if(loadFiles.ShowDialog()==DialogResult.OK)
{
如果(!gerbViewActive)
{
gerbView=新流程();
gerbView.EnableRaisingEvents=true;
gerbView.Exited+=新事件处理程序(gerbView_Exited);
gerbView.StartInfo.FileName=@“C:\Program Files\Software Compartments\gerbView\gerbView.exe”;
gerbView.StartInfo.WindowStyle=ProcessWindowStyle.Maximized;
gerbView.Start();
gerbViewActive=true;
}
//在运行cmd进程之前,请等待GerbView加载。
《睡眠》(2000年);
string[]files=loadFiles.filename;
cmd=新进程();
cmd.StartInfo.FileName=“cmd.exe”;
cmd.StartInfo.RedirectStandardInput=true;
cmd.StartInfo.UseShellExecute=false;
cmd.StartInfo.WindowStyle=ProcessWindowStyle.Hidden;
cmd.StartInfo.WorkingDirectory=@“C:\Program Files\Software Compartments\GerbView\”;
cmd.Start();
使用(StreamWriter cmdInput=cmd.StandardInput)
{
for(int index=0;index

任何帮助或建议都将不胜感激。

首先,您正在执行的命令行工具必须尝试定位现有流程并与之通信。我会跳过运行
cmd.exe
,自己运行每个
gerbview.exe/add
进程。然后,您可以
.WaitForExit()
,以确保在启动另一个进程之前,每个进程都已完成。然而,这可能还不够

接下来,需要在主UI进程上执行
.WaitForInputIdle()
,直到主线程清除其win32事件队列为止。这可能是他们的文件打开命令行成功与之通信的必要条件

明确地说,您需要的最小步骤集是

  • 启动主进程“gerbview.exe”,然后循环文件;
    • 主进程。waitforinputile
    • 使用参数$“/添加“{filename}”启动“gerbview.exe”
    • .WaitForExit的“gerbview.exe”进程
由于启动与主UI相同的查看器可执行文件并打开每个文件,因此它可能是“windows子系统”可执行文件,而不是控制台可执行文件。cmd.exe将启动进程,但在退出之前不会阻止进程。确定它已经退出的唯一方法是自己开始这个过程

您还可以尝试向查看器进程的窗口句柄发布或发送一些noop窗口消息,以确保.waitForInput有一些新的输入等待


所有这些都不能保证这一过程会起作用。这完全取决于第三方应用程序的编写方式。

“接下来,您需要.WaitForInputIdle()”和“这可能是一个必要条件”-但这仍然是一个假设,可能不是这样。如果这不起作用,问题就会变得非常棘手。我的程序片段显示我正在打开一个GerbView进程来激活程序,因为没有第一个实例,我无法自动向查看器添加多个文件。我打开cmd.exe进程,以便自动运行/add参数。我无法手动运行/add,因为它无法实现自动化。如果我使用.WaitForExit()方法,它将锁定等待GerbView退出的程序,这是我不希望看到的。我试过j