1.程序代码

// 手动提取目录路径
static std::wstring ExtractDirectory(const std::wstring& filePath)
{
    // 查找最后一个路径分隔符
    size_t lastSlash = filePath.find_last_of(L"/\\");
    if (lastSlash != std::wstring::npos) {
        return filePath.substr(0, lastSlash);
    }
    // 如果没有找到分隔符,返回空字符串(表示当前目录)
    return L"";
}

// 执行并等待控制台程序(手动路径处理)
static DWORD ExecAndWaitConsole(std::wstring lpszAppPath, std::wstring lpParameters, std::wstring lpszDirectory, DWORD dwMilliseconds)
{
    DWORD dwExitCode = (DWORD)-1;
    HANDLE hProcess = NULL;
    std::wstring originalDirectory;
    bool directoryChanged = false;

    // 1. 保存当前目录
    wchar_t currentDir[MAX_PATH];
    DWORD dirLen = GetCurrentDirectory(MAX_PATH, currentDir);
    if (dirLen > 0 && dirLen < MAX_PATH) {
        originalDirectory = currentDir;
    }

    // 2. 确定工作目录
    std::wstring workingDirectory;

    if (!lpszDirectory.empty()) {
        // 使用用户指定的目录
        workingDirectory = lpszDirectory;
    }
    else {
        // 自动设置为应用程序所在目录(手动处理)
        workingDirectory = ExtractDirectory(lpszAppPath);
        if (workingDirectory.empty()) {
            workingDirectory = originalDirectory;
        }
    }

    // 3. 切换到工作目录
    if (!workingDirectory.empty()) {
        // 规范化路径(将 / 转换为 \)
        std::wstring normalizedPath = workingDirectory;
        std::replace(normalizedPath.begin(), normalizedPath.end(), L'/', L'\\');

        if (SetCurrentDirectory(normalizedPath.c_str())) {
            directoryChanged = true;
        }
    }

    // 准备启动信息
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // 构建命令行
    std::wstring commandLine = L"\"";
    commandLine += lpszAppPath;
    commandLine += L"\" ";
    commandLine += lpParameters;

    std::vector<wchar_t> cmdLineBuffer(commandLine.begin(), commandLine.end());
    cmdLineBuffer.push_back(L'\0');

    // 创建进程
    BOOL bSuccess = CreateProcess(
        lpszAppPath.c_str(),            // 应用程序路径
        cmdLineBuffer.data(),           // 命令行
        NULL,                           // 进程安全属性
        NULL,                           // 线程安全属性
        FALSE,                          // 不继承句柄
        CREATE_NO_WINDOW,               // 控制台程序,不创建窗口
        NULL,                           // 使用父进程环境变量
        NULL,                           // 工作目录(使用当前目录)
        &si,                            // 启动信息
        &pi                             // 进程信息
    );

    if (!bSuccess) {
        DWORD error = GetLastError();
        // 在返回前恢复原始目录
        if (directoryChanged && !originalDirectory.empty()) {
            SetCurrentDirectory(originalDirectory.c_str());
        }
        return (DWORD)-1;
    }

    // 立即关闭线程句柄
    CloseHandle(pi.hThread);
    hProcess = pi.hProcess;

    // 等待进程结束
    DWORD waitResult = WaitForSingleObject(hProcess, dwMilliseconds);

    switch (waitResult) {
    case WAIT_OBJECT_0:
        if (GetExitCodeProcess(hProcess, &dwExitCode)) {
            // 成功获取退出码
        }
        else {
            dwExitCode = (DWORD)-1;
        }
        break;

    case WAIT_TIMEOUT:
        TerminateProcess(hProcess, 1);
        dwExitCode = (DWORD)-1;
        break;

    case WAIT_FAILED:
    default:
        TerminateProcess(hProcess, 1);
        dwExitCode = (DWORD)-1;
        break;
    }

    // 关闭进程句柄
    if (hProcess) {
        CloseHandle(hProcess);
    }

    // 4. 恢复原始目录
    if (directoryChanged && !originalDirectory.empty()) {
        SetCurrentDirectory(originalDirectory.c_str());
    }

    return dwExitCode;
}

2.调用范例

	//执行exe
	std::wstring paraStdW = m_ParaStr.toStdWString();
	std::wstring exeStdW = m_ExeFullFilenameStr.toStdWString();
	ExecAndWaitConsole(exeStdW, paraStdW, L"", INFINITE);
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐