Starting a process -
ProcessStartInfo psi = new ProcessStartInfo("G:\SampleWinApp.exe");
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process prcs = Process.Start(psi);
Send WM_CLOSE using PostMessage
const int WM_CLOSE = 0x0010;
public void SendCloseSignal(Process proc)
{
uint uiPid = (uint) proc.Id;
bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
if (!bResult && Marshal.GetLastWin32Error() == 0) {
object objWnd = processWnd[uiPid];
if (objWnd != null) {
IntPtr ptrWnd = (IntPtr) objWnd;
PostMessage(ptrWnd, WM_CLOSE, 0, 0);
return;
}
}
foreach (ProcessThread thread in proc.Threads) {
PostThreadMessage((uint) thread.Id, WM_CLOSE, UIntPtr.Zero, IntPtr.Zero);
}
}
private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
{
uint uiPid = 0;
if (GetParent(hwnd) == IntPtr.Zero)
{
GetWindowThreadProcessId(hwnd, ref uiPid);
if (uiPid == lParam)
{
processWnd[uiPid] = hwnd;
return false;
}
}
return true;
}
Start exe with CreateNoWindow = false
, WM_CLOSE message is send and application shuts down gracefully.
With CreateNoWindow = true
, WM_CLOSE message never reach the proess. Even PostThreadMessage does not seem to work. Is there any way to send WM_CLOSE message? I have search for a day to find a solution to this.. no luck.
Edit: A windows service is installed for every application. Starting/Stopping the service starts/stops the application. Currently we kill the application on service stop. As its a brute force kill, applications do not die gracefully. Some of the applications listen for CTRL signals. Now, I just need some way to send WM_CLOSE message to these applications.
Edit2: If there is a window, WM_CLOSE triggers a CTRL_CLOSE_EVENT. But when any process is started with CreateNoWindow = true, this never triggers.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…