CreateProcess的命令行参数
最近使用CreateProcess创建rundll32.exe进程,发现并没有正常加载DLL,后来才发现是命令行参数传错了,CreateProcess并不是我想象的那样,网上找了一下,发现还有许多东西不是想的那么简单。下面的文字翻译自《INFO: Understanding CreateProcess and Command-line Arguments》
创建32位进程时CreateProcess的行为
案例1
如果传递了ApplicationName参数,且CommandLine参数是NULL,那么ApplicationName参数同时也会被当做CommandLine参数。但这并不意味着你可以在ApplicationName参数中添加额外的命令行参数。比如下面的代码就无法成功创建进程:
CreateProcess("c:\\MyApp.exe Param1 Param2", NULL, ... );
案例2
如果传递了CommandLine参数,且ApplicationName参数是NULL,那么CreateProcess会尝试从CommandLine中提取ApplicationName。
案例3
当ApplicationName和CommandLine两个参数同时都使用的时候,就会体现出CreateProcess的灵活性了(也是容易混淆的地方)。这时候允许你指明要执行的程序以及要传给程序的完整的命令行参数。你也许会认为传递给创建的程序的命令行参数是ApplicationName和CommandLine的组合,但实际上不是这样的。实际情况是,由CreateProcess创建的进程可以接收一个指定的参数填充到argv[0],下面的例子就会产生这种不正常现象:
CreateProcess( "c:\\MyApp.exe", "Param1 Param2 Param3", ...);
MyApp的命令参数将会是这样的:
argv[0] == "Param1"
argv[1] == "Param2"
argv[2] == "Param3"
此外,在《Windows核心编程》中提到,CreateProcess函数的lpCommandLine参数类型为LPTSTR,这意味着CreateProcess期望你将传递一个非常量字符串的地址,从内部来讲,CreateProcess实际上要修改你传递给它的命令行字符串,不过,在CreateProcess返回之前,它将该字符串恢复为它的原始形式。所以如果传递的是常量字符串,那么可能会引发违规访问的异常。
所以,CreateProcess正确的写法应该这样:
TCHAR szPath[MAX_PATH] = {L"C:\\Windows\\System32\\rundll32.exe"};
TCHAR szCmdLine[MAX_PATH] = {
L"C:\\Windows\\System32\\rundll32.exe"
L" D:\\Test.dll,TestFunc" // 注意前面的空格
};
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi = {0};
BOOL bRet = FALSE;
bRet = CreateProcess(
szPath,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
推荐阅读
-
Oracle 11g版本EXPDP 的COMPRESSION参数压缩比堪比“gzip -9”
-
从屏幕参数上如何选择一款适合自己的平板电脑
-
Linux Shell 如何获取参数的方法
-
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法_PHP教程
-
编写一个函数 reverse_string(char * string)(递归实现) 实现:将参数字符串中的字符反向排列。 要求:不能使用C函数库中的字符串操作函数。
-
编写一个函数reverse_string(char * string)(递归实现)实现:将参数字符串中的字符反向排列。 要求:不能使用C函数库中的字符串操作函数
-
【Vue2+Vue3】props参数赋值给data属性【如何实现响应式变化-如何解决值传递无法响应式的问题】
-
CodeIgniter RestServer中put请求获取不到参数的问题解决
-
Oracle创建带有参数的视图代码介绍
-
Vue + Element-ui的下拉框el-select获取额外参数详解