c++-win32-执行控制台程序并设置初始工作目录
·
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);
更多推荐
所有评论(0)