Как закрыть Discord программно? - PullRequest
2 голосов
/ 27 марта 2020

Я хотел бы закрыть Discord программно, надлежащим образом (без вызова Process.Kill () ).

AFAIK Обычный способ элегантно закрыть программу - проверить, есть главное окно, связанное с процессом (например: Process.MainWindowHandle != IntPtr.Zero), а затем вызовите Process.CloseMainWindow(). Он отправит сообщение о закрытии в главное окно.

Он не работает с Discord, поскольку главное окно может быть уже закрыто, а программа все еще работает в фоновом режиме. Обычный способ выйти из Discord - щелкнуть правой кнопкой мыши значок на панели задач и выбрать «Выход из Discord», а не просто закрыть главное окно.

Когда Windows завершает работу, Discord автоматически закрывается. Я не думаю, что Windows просто убивает все процессы Discord, так что, может быть, есть способ сделать что-то похожее на то, что делает Windows?

1 Ответ

0 голосов
/ 28 марта 2020

Когда Windows завершает работу, оно отправляет приложению кучу событий, включая WM_ENDSESSION и WM_QUIT. Кроме того, этот процесс сложен и его нелегко воспроизвести. Однако вы можете переопределить обработчик сообщений System.Windows.Forms.Control.WndProc, чтобы сделать что-то, прежде чем система обработает сообщение.

Если вы хотите выйти из приложения программным способом, попробуйте отправить эти 2 сообщения в процесс, используя public static extern IntPtr PostMessage.

Пример:

[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

const uint WM_QUERYENDSESSION = 0x11
const uint ENDSESSION_CLOSEAPP = 0x1;

public static void SendMessageToProcess(string processName)
{
    Process[] processList = Process.GetProcesses();
    foreach (var p in processList)
    {
        if (p.ProcessName.Equals(processName))
        {
            IntPtr hWnd = p.MainWindowHandle;
            PostMessage(hWnd, WD_QUERYENDSESSION, true, ENDSESSION_CLOSEAPP);
        }
    }
}

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override void WndProc(ref Message m) 
{
    switch (m.Msg)
    {
        case WM_QUERYENDSESSION:
            //Do something
    }
    base.WndProc(ref m);
}
...