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



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

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

我知道Process类使用FileName和Arguments属性可以很容易地做到这一点,但我需要向同一实例添加更多文件。执行此操作的命令是gerview/add{filename}

最后一个命令将启动程序,如果实例已经打开,它只会添加一个要查看的附加文件。这就是我的问题所在。在我得到最终解决方案(见下文(之前,我的程序一直在打开多个实例(尽管使用了/add参数(,这可能是因为程序在执行_add

Process gerbView;
Process cmd;
bool gerbViewActive;
// The is the windows form constructor
public WindowsFormGUI()
{
InitializeComponent();
gerbViewActive = false;
}
private void buttonRunProgram_Click(object sender, EventArgs e)
{
OpenFileDialog loadFiles = new OpenFileDialog
{
Multiselect = true,
InitialDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).FullName
};
if (loadFiles.ShowDialog() == DialogResult.OK)
{
if (!gerbViewActive)
{
gerbView = new Process();
gerbView.EnableRaisingEvents = true;
gerbView.Exited += new EventHandler(GerbView_Exited);
gerbView.StartInfo.FileName = @"C:Program FilesSoftware CompanionsGerbViewgerbview.exe";
gerbView.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
gerbView.Start();
gerbViewActive = true;
}

// wait until GerbView loads before running the cmd process.
Thread.Sleep(2000);

string[] files = loadFiles.FileNames;
cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.StartInfo.WorkingDirectory = @"C:Program FilesSoftware CompanionsGerbView";
cmd.Start();
using (StreamWriter cmdInput = cmd.StandardInput)
{
for (int index = 0; index < files.Length; index++)
{
cmdInput.WriteLine("gerbview.exe /add " + files[index]);
}
}
cmd.Close();
}
}
private void GerbView_Exited(object sender, EventArgs e)
{
gerbViewActive = false;
gerbView.Close();
}

如有任何帮助或建议,我们将不胜感激。

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

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

明确地说,你想要的最小步骤集是;

  • 启动主进程"gerpview.exe";,然后循环文件;
    • 主进程。WaitForInputIdle
    • "开始";gerpview.exe";具有自变量$"/添加";{filename}">
    • WaitForExit of this";gerpview.exe";过程

由于您正在启动与主UI相同的查看器可执行文件并打开每个文件,因此很可能是一个";windows子系统";可执行文件而不是控制台可执行文件。cmd.exe将启动进程,但在退出之前不会阻止。确定它已经退出的唯一方法是自己开始这个过程。

您也可以尝试向查看器进程的窗口句柄发布或发送一些noop窗口消息,以确保这一点。WaitForInputIdle有一些新的输入要等待。

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

相关内容

  • 没有找到相关文章