重启程序

三种方法记录:

1.OnDestroy消息,(最好的方法)

void CMFCApplication9Dlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    int _nRestart = GetPrivateProfileInt(_T("App"),_T("Restart"),NULL,_T("c:\\1.ini"));

    if(_nRestart)
    { 
        WritePrivateProfileString(_T("App"), _T("Restart"), _T("0"), _T("c:\\1.ini"));

        TCHAR _pBuf[MAX_PATH];

        GetModuleFileName(NULL, _pBuf, MAX_PATH);

        STARTUPINFO _startupInfo;
        PROCESS_INFORMATION _procInfo;

        memset(&_startupInfo, 0, sizeof(STARTUPINFO));
        _startupInfo.cb = sizeof(STARTUPINFO);

        // 最重要的地方

        ::CreateProcess(_pBuf, NULL, NULL, NULL, FALSE,
            NORMAL_PRIORITY_CLASS, NULL, NULL, &_startupInfo, &_procInfo);
    }

扫描二维码关注公众号,回复: 12675696 查看本文章

2.cmd脚本形式,动态生成,会造成安全软件拦截

void Restart(IN CString strAppName_)
{
    FILE* pf;
    ::DeleteFile(L"restart.cmd");                            //确保删除上次遗留下的批处理文件
    errno_t err = ::_wfopen_s(&pf, L"restart.cmd", L"w");    //“w”表示打开一个空文件以进行写入。如果该文件存在,其内容将被销毁。
    if (err == 0)                                            //restart.cmd不存在时,err == 0
    {
        TCHAR szExeName[1024];
        GetModuleFileName(NULL, szExeName, 1024);            //获取进程的名称
        _ftprintf(pf, _T("@echo off\n:a\n taskkill /f /im %s \n start \"\" \"%s\" \ndel %%0"), strAppName_.GetBuffer(),szExeName);
        //restart.exe为需要重启的进程名称
//taskkill /f(指定要强行终止的进程) /im( image name 可以理解为指定要终止的进程名名称)
//%%0在批处理中表示%0,del %%0(删除批处理自身)
        fclose(pf);
    }
    else
    {
    //    cout << "can not open restart.cmd" << endl;
    }

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof si);
    ZeroMemory(&pi, sizeof pi);
    si.cb = sizeof si;
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    TCHAR winSysDir[1024];
    ZeroMemory(winSysDir, sizeof winSysDir);
    ::GetSystemDirectory(winSysDir, 1024);
    std::wstring appName = winSysDir;
    appName += L"\\cmd.exe";
    BOOL bRet = CreateProcess(
        appName.c_str(),
        L"/c restart.cmd",                    //执行字符串指定的命令然后终断
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi);

    if (bRet == FALSE)
    {
        int err = GetLastError();
        //cout << "can not restart test, error code:" << err << endl;
    }
}

3.实际只改了进程号,某些变化并没有生效

void Restart(IN HWND hwnd_)
{
    //发送退出程序消息
    ::SendMessage(hwnd_, WM_CLOSE, 0, 0);
    //MFC程序可以用下面这行代码
    //::PostMessage(AfxGetMainWnd()->m_hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL);

    //获取exe程序当前路径
    TCHAR szAppName[MAX_PATH];
    ::GetModuleFileName(NULL, szAppName, MAX_PATH);

    std::wstring strCommandline = L"\"-scmd\" \"appid\" \"100\"";
    wchar_t pszCommandline[1024] = { 0 };
    wcscpy_s(pszCommandline, strCommandline.c_str());

    //创建进程重启程序
    STARTUPINFO StartInfo;
    memset(&StartInfo, 0, sizeof(STARTUPINFO));
    StartInfo.cb = sizeof(STARTUPINFO);
    PROCESS_INFORMATION procStruct;
    memset(&procStruct, 0, sizeof(PROCESS_INFORMATION));
    //
    ::CreateProcessW(
        (LPCTSTR)szAppName,
        (LPWSTR)pszCommandline,//命令行参数放置于此
        NULL,
        NULL,
        FALSE,
        NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &StartInfo,
        &procStruct);
}

猜你喜欢

转载自blog.csdn.net/greless/article/details/105713472