使用CreateProcess运行批处理文件
Use CreateProcess to Run a Batch File
我正在尝试使用CreateProcess启动一个新的环境块,并在新的环境中运行一个批处理文件。我已经阅读了CreateProcess的msdn示例,并得出了如下所示的代码。
发生了什么,它将打开新的命令提示符,并在那里停止。由于某种原因,它不会运行我的.bat文件。使用系统("CALL路径")将调用.bat文件。
#include <iostream>
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>
#include <strsafe.h>
#define BUFSIZE 4096
int main()
{
//system("CALL C:\HFSS\setup_vars.bat");
//return 0;
LPWCH chNewEnv;
LPTSTR lpszCurrentVariable;
DWORD dwFlags = 0;
TCHAR szAppName[] = TEXT("C:\windows\system32\cmd.exe");
TCHAR cmdArgs[] = TEXT("C:\HFSS\setup_var.bat");
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL fSuccess;
// Copy environment strings into an environment block.
chNewEnv = GetEnvironmentStrings();
lpszCurrentVariable = (LPTSTR)chNewEnv;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MySetting=A"))))
{
printf("String copy failedn");
return FALSE;
}
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MyVersion=2"))))
{
printf("String copy failedn");
return FALSE;
}
// Terminate the block with a NULL byte.
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
*lpszCurrentVariable = (TCHAR)0;
// Create the child process, specifying a new environment block.
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
#ifdef UNICODE
dwFlags = CREATE_UNICODE_ENVIRONMENT;
#endif
fSuccess = CreateProcess(szAppName, cmdArgs, NULL, NULL, TRUE, dwFlags,
(LPVOID)chNewEnv, // new environment block
NULL, &si, &pi);
if (!fSuccess)
{
printf("CreateProcess failed (%d)n", GetLastError());
return FALSE;
}
std::cout << "In new environmentn";
WaitForSingleObject(pi.hProcess, INFINITE);
return TRUE;
}
一些问题:
- 您需要将
/C
选项传递给cmd.exe
,以便使其执行.bat文件 CreateProcess
的第二个参数必须是可修改的字符串。不是字面意思- 您需要对文字中的反斜杠字符进行转义
- CCD_ 4指向CCD_。您不能修改该缓冲区。你需要分配一个足够长的新缓冲区,并将环境复制到其中。然后添加你的修改
- 环境块以双null结尾。标准字符串函数对以双null结尾的字符串没有任何用处
- 使用像
StringCchCopy
这样的函数而不是C运行时函数只是令人困惑。不要把MSDN示例代码看作是风格的典范 - C字符串是一个可以使用的绑定。但是您使用C++,所以使用
std::wstring
和其他标准库类和函数 - 在导入
Windows.h
之前,您需要定义WINDOWS_LEAN_AND_MEAN
- 对于C++,
int main(void)
是不正确的。无自变量main
是int main()
以下代码向您展示了如何做到这一点:
#include <cstring>
#include <string>
#include <iostream>
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>
std::wstring GetEnvString()
{
wchar_t* env = GetEnvironmentStrings();
if (!env)
abort();
const wchar_t* var = env;
size_t totallen = 0;
size_t len;
while ((len = wcslen(var)) > 0)
{
totallen += len + 1;
var += len + 1;
}
std::wstring result(env, totallen);
FreeEnvironmentStrings(env);
return result;
}
int main()
{
std::wstring env = GetEnvString();
env += L"myvar=boo";
env.push_back(' '); // somewhat awkward way to embed a null-terminator
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
wchar_t cmdline[] = L"cmd.exe /C C:\Desktop\MyBatFile.bat";
if (!CreateProcess(NULL, cmdline, NULL, NULL, false, CREATE_UNICODE_ENVIRONMENT,
(LPVOID)env.c_str(), NULL, &si, &pi))
{
std::cout << GetLastError();
abort();
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
相关文章:
- 如何在 c++ 窗口中将参数和返回的退出值传递到批处理文件/从批处理文件获取返回的退出值
- 从之前添加的批处理文件中删除单词
- 无法从C++ Windows 服务执行批处理文件
- 如何将批处理文件的输出读取到C 中的字符串中
- cmake:生成批处理文件调用cl.exe
- 如何运行批处理文件和读取输出
- GetCommandLine():无法从批处理文件(GCC-Compiler)传递多行参数
- exe文件不被识别为内部或外部命令,可操作的程序或批处理文件在C++
- 您如何使用System()调用带有引号的参数的批处理文件
- 重命名批处理文件(删除名称中的一些符号)(python/matlab/shell)
- 对桌面进行了更改.ini使用批处理文件,但文件夹图标不会更改
- 如何将字符串转换为批处理文件中的整数
- 为什么我不能在Windows Server 2008中使用System()从服务启动批处理文件
- 通过批处理文件在多个文件上添加标头
- 替代System(),用于在程序中运行批处理文件
- Qt Creator:如何运行windows批处理文件并获得结果
- 使用CreateProcess运行批处理文件
- 在没有窗口的情况下运行C++非托管控制台应用程序(不是批处理文件)
- c++运行批处理文件而不重定向输出
- 应用程序运行无法删除文件的批处理文件