Как я могу убить, а затем перезапустить процесс в C ++? - PullRequest
0 голосов
/ 14 мая 2009

Я хотел бы убить и перезапустить explorer.exe из моего приложения C ++, как бы я это сделал?

Ответы [ 6 ]

3 голосов
/ 14 мая 2009

Определите главное окно приложения (например, с помощью FindWindow) и отправьте ему WM_QUIT.

Используйте SendMessageTimeout () для его отправки; эта функция позволяет вам указать, как долго вы готовы ждать, пока приложение справится с этим. Если SendMessageTimeout () возвратился из-за истечения времени ожидания, прибегните к TerminateProcess ().

Вот ссылка на спецификацию SendMessageTimeout: http://msdn.microsoft.com/en-us/library/ms644952(VS.85).aspx

2 голосов
/ 14 мая 2009

Вы можете использовать CreateProcess для вызова explorer.exe и TerminateProcess для его уничтожения. ExitProcess , как упомянуто в ответе выше, относится только к текущему процессу (то есть процессу, из которого вы вызываете ExitProcess).

Вы также можете использовать OpenProcess для доступа к процессу, который уже создан другими средствами.

OpenProcess

TerminateProcess

BOOL WINAPI TerminateProcess
(
  __in  HANDLE hProcess,
  __in  UINT uExitCode
);

CreateProcess имеет следующую подпись:

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);

Обратите внимание на последний параметр, для которого вы должны передать указатель на структуру PROCESS_INFORMATION. Эта структура содержит дескриптор, идентификатор процесса и т. Д., Когда CreateProcess возвращает.

typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;
  HANDLE hThread;
  DWORD  dwProcessId;
  DWORD  dwThreadId;
}PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

Если у вас уже есть процесс, созданный другими средствами, то информация о дескрипторе процесса и т. Д. Не будет вам доступна. В этом случае вы должны перечислить процессы и найти тот, который вас интересует. Это показано здесь, на MSDN. Перечисление всех процессов

1 голос
/ 15 мая 2009
#include <cstdio>
#include <windows.h>
#include <tlhelp32.h>

void LaunchExplorer() {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof( si ) );

    si.cb = sizeof( si );

    CreateProcess( "explorer.exe", NULL, NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
}

int main( int, char *[] ) {
    PROCESSENTRY32 entry;
    entry.dwFlags = sizeof( PROCESSENTRY32 );

    HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL );

    if ( Process32First( snapshot, &entry ) == TRUE ) {
        while ( Process32Next( snapshot, &entry ) == TRUE ) {
            if ( stricmp( entry.szExeFile, "explorer.exe" ) == 0 ) {
                HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, entry.th32ProcessID );

                TerminateProcess( hProcess, 0 );

                CloseHandle( hProcess );

                break;
            }
        }

        LaunchExplorer();
    }

    CloseHandle( snapshot );

    return 0;
}
0 голосов
/ 19 июля 2016

Мой ответ слишком поздно, но на всякий случай для того, кому это нужно ...

/////////////////////////////////////////////////////////////////////////////
bool _killExplorer()
{
    CString strCmd1_KillExplorer = _T("taskkill /f /im explorer.exe");

    PROCESS_INFORMATION pi;
    STARTUPINFO si = { sizeof si };
    bool bCmd = true;
    TCHAR szCmdTmp[MAX_PATH];
    _tcscpy(szCmdTmp, (LPCTSTR)strCmd1_KillExplorer);
    if (CreateProcess(NULL, (LPTSTR)szCmdTmp, NULL, NULL, NULL, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
        WaitForSingleObject(pi.hProcess, INFINITE);
        DWORD dwCode = 0;
        if (!GetExitCodeProcess(pi.hProcess, &dwCode))
            bCmd = false;
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    else {
        bCmd = false;
    }
    return bCmd;
}   // _killExplorer()


bool _startExplorer()
{
    CString strCmd2_StartExplorer = _T("%systemroot%\\sysnative\\cmd.exe /c start /B explorer.exe");
    TCHAR szCmdTmp[MAX_PATH];
    DWORD dwSize = MAX_PATH;
    ExpandEnvironmentStrings( (LPCTSTR)strCmd2_StartExplorer, szCmdTmp, dwSize );

    PROCESS_INFORMATION pi;
    STARTUPINFO si = { sizeof si };
    bool bCmd = true;
    if (CreateProcessW( NULL, (LPTSTR)szCmdTmp, NULL, NULL, NULL, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
        WaitForSingleObject(pi.hProcess, INFINITE);
        DWORD dwCode = 0;
        if (!GetExitCodeProcess(pi.hProcess, &dwCode))
            bCmd = false;
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    else {
        bCmd = false;
    }
    return bCmd;
}   // _startExplorer()


void RestartExplorer()
{
    if (_killExplorer()) {
        _startExplorer();
    }
}
0 голосов
/ 18 мая 2009

Никогда не убивайте Проводника: это не имеет никакого смысла!
Просто используйте Обновление Win32 Shell apis.

0 голосов
/ 14 мая 2009

Поскольку современные системы Windows совместимы с POSIX, вы можете отправить сигнал KILL внешним процессам. Однако обратите внимание, что это будет преобразовано в вызов TerminateProcess, так что вы можете просто использовать это.

http://www.mkssoftware.com/docs/man1/kill.1.asp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...