外部アプリを起動し、それとすべての子プロセスが終了するのを待つアプリケーションを作成しています。
private int RunCmdAndGetExitCode(string command, string args, ProcessWindowStyle windowStyle, WaitEnum wait)
{
Process scriptProc = new Process();
scriptProc.StartInfo.FileName = command;
scriptProc.StartInfo.Arguments = args;
scriptProc.StartInfo.WindowStyle = windowStyle;
if (scriptProc.Start())
{
if (wait == WaitEnum.MainProcess)
{
scriptProc.WaitForExit();
return scriptProc.ExitCode;
}
else if(wait == WaitEnum.None)
{
return 0;
}
else if (wait == WaitEnum.ChildProcesses)
{
ProcessMonitorThread _procmon = new ProcessMonitorThread(this, scriptProc);
while (ThreadCount != 0)
{
Thread.Sleep(500);
}
return 0;
}
}
return -1;
}
ProcessMonitorThread
から継承するクラスですBackgroundWorker
public class ProcessMonitorThread : BackgroundWorker
{
private IChildCounter _Counter;
private Process _processToMonitor;
public ProcessMonitorThread(IChildCounter counter, Process processToMonitor)
{
_Counter = counter;
_Counter.ThreadCount++;
_processToMonitor = processToMonitor;
this.DoWork += new DoWorkEventHandler(ProcessMonitorThread_DoWork);
this.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ProcessMonitorThread_RunWorkerCompleted);
this.RunWorkerAsync();
}
void ProcessMonitorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_Counter.ThreadCount--;
}
void ProcessMonitorThread_DoWork(object sender, DoWorkEventArgs e)
{
int processid = _processToMonitor.Id;
_processToMonitor.WaitForExit();
foreach (int _childid in GetChildProcessIDs(processid))
{
Process ps = Process.GetProcessById(_childid);
new ProcessMonitorThread(_Counter, ps);
}
}
List<Int32> GetChildProcessIDs(int ProcessID)
{
List<Int32> _ChildProcesses = new List<Int32>();
// Use the ObjectQuery to get the list of configured printers
System.Management.ObjectQuery oquery =
new System.Management.ObjectQuery("SELECT * FROM Win32_Process WHERE ParentProcessId =" + ProcessID);
System.Management.ManagementObjectSearcher mosearcher =
new System.Management.ManagementObjectSearcher(oquery);
System.Management.ManagementObjectCollection _AllChildProcesses = mosearcher.Get();
foreach (ManagementObject _cprocess in _AllChildProcesses)
{
Int32 _processid;
_processid = Convert.ToInt32(_cprocess["ProcessId"]);
_ChildProcesses.Add(_processid);
}
return _ChildProcesses;
}
}
印刷可能なアプリを起動すると、splwow64が起動し、そのプロセスが子プロセスの1つになります。問題は、アプリを閉じたときに、splwow64を起動してもアプリが閉じず、何らかのタイムアウトを待つことです。私が起動したアプリとそのすべての子プロセスが終了したことをアプリが報告するのは、splwow64が終了したときだけです。どちらが正しい。しかし、私は本当にsplwow64を待ちたくありません。
システムプロセスまたはプロセスの終了後に実行されたままになる可能性のあるプロセスを特定する方法はありますか?
splwow64という名前のプロセスを無視できることは知っていますが、それは私には少し回避策のようです。