CreateProcess 调用bat 失败!

samuelo 2010-02-09 04:11:02
d:\1\a.exe 使用CreateProcess调用d:\2\b.bat.
代码这么写的:
CreateProcess( TEXT( "cmd.exe" ),
TEXT( "\c c:\\zzz.bat" ),
NULL,
NULL,
FALSE,
dwCreationFlag,
NULL,
TEXT( "C:\\" ), //当前目录
&si,
pProcessInfo );

执行失败。GetlastError() == 2(系统找不到指定文件)。
不知道哪里错了。文件地址都硬编码了。

用CreateProcess调bat有什么要注意的吗?
另外我看到有人写:
TEXT( "\c c:\\zzz.bat" ),

\c是什么意思?
...全文
987 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
tompaz 2010-09-15
  • 打赏
  • 举报
回复
试过了,好像也是不行的
samuelo 2010-02-09
  • 打赏
  • 举报
回复
总结一下使用CreateProcess 调用bat 的方法。

第一个参数,cmd.exe的完全路径。(保留 wltg2001 对此的异议)
第二个参数:/c 双引号括起来的bat完全路径。例如 /c "d:\\Feb 9\\aaa.bat"
第八个参数:bat的目录。例如d:\\Feb 9\\
第九参数:不为空。
第十个参数:不为空。
samuelo 2010-02-09
  • 打赏
  • 举报
回复
我本来也像你那么做的。在XP和2003上测试,有时可以成功,少数情况失败。
wltg2001 2010-02-09
  • 打赏
  • 举报
回复
10楼:
MSDN说对于bat文件,第一个参数必须设cmd.exe。我想不能为NULL吧?
======================
MSDN我没看,不过我的代码我试过的,如果不能运行,我不会说的
gamezealot 2010-02-09
  • 打赏
  • 举报
回复
引用 11 楼 wltg2001 的回复:
第一个参数是必须指定全部路径的,如果第一个参数为NULL。
则第二个参数可以设置为_T(""cmd.exe c:\\zzz.bat").这样才会向楼主你说的那样安装windows的规则查找可执行文件。MSDN上说的很清楚:
=====================
我发现好多人答题之前都不实验的,你就是在“运行”窗口中直接输入:cmd.exe c:\\zzz.bat都不会执行的

我对我没有做实验表示抱歉,MSDN也没仔细看。我上面回复的适合其他的程序而不是cmd.exe。
samuelo 2010-02-09
  • 打赏
  • 举报
回复
10楼:
MSDN说对于bat文件,第一个参数必须设cmd.exe。我想不能为NULL吧?

BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

Parameters
lpApplicationName
[in] Pointer to a null-terminated string that specifies the module to execute. The specified module can be a Windows-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification. The function will not use the search path. If the file name does not contain an extension, .exe is assumed. Therefore, if the file name extension is .com, this parameter must include the .com extension.

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space-delimited token in the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the following order:

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine should specify the executable module as well as its arguments.

To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the name of the batch file.


8楼:
我看了MSDN,可惜没看仔细。当第一个参数NULL,这时系统才会按环境变量去找文件。
wangk 2010-02-09
  • 打赏
  • 举报
回复
引用 11 楼 wltg2001 的回复:
第一个参数是必须指定全部路径的,如果第一个参数为NULL。
则第二个参数可以设置为_T(""cmd.exe c:\\zzz.bat").这样才会向楼主你说的那样安装windows的规则查找可执行文件。MSDN上说的很清楚:
=====================
我发现好多人答题之前都不实验的,你就是在“运行”窗口中直接输入:cmd.exe c:\\zzz.bat都不会执行的


惭愧,被命中了。某只凭经验答了一下,误导他人啊
wltg2001 2010-02-09
  • 打赏
  • 举报
回复
第一个参数是必须指定全部路径的,如果第一个参数为NULL。
则第二个参数可以设置为_T(""cmd.exe c:\\zzz.bat").这样才会向楼主你说的那样安装windows的规则查找可执行文件。MSDN上说的很清楚:
=====================
我发现好多人答题之前都不实验的,你就是在“运行”窗口中直接输入:cmd.exe c:\\zzz.bat都不会执行的
wltg2001 2010-02-09
  • 打赏
  • 举报
回复
不要用cmd.exe,它不接受批处理文件名作为参数,直接调用,另外,命令字集不能写在CreateProcess中,必须要先定义在一个字符串变量中,因为CreateProcess要写回的,常量无法写回,所以执行时会出现内存存取错。写成如下代码就行了:
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;

PROCESS_INFORMATION pProcessInfo;
WCHAR p[]=L"c:\\zzz.bat"
CreateProcess( NULL,p, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS ,NULL, TEXT( "C:\\" ), &si,&pProcessInfo );
cnlm2 2010-02-09
  • 打赏
  • 举报
回复
楼上正解,多看msdn
gamezealot 2010-02-09
  • 打赏
  • 举报
回复
第一个参数是必须指定全部路径的,如果第一个参数为NULL。
则第二个参数可以设置为_T(""cmd.exe c:\\zzz.bat").这样才会向楼主你说的那样安装windows的规则查找可执行文件。MSDN上说的很清楚:
If lpApplicationName is NULL, the first white-space – delimited token of the command line specifies the module name. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches for the executable file in the following sequence:

1.The directory from which the application loaded.
2.The current directory for the parent process.
3.The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
Windows Me/98/95: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
4.The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
5.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
6.The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
WizardK 2010-02-09
  • 打赏
  • 举报
回复
也可以调用CRT的SYSTEM函数
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
你用的是CreateProcess
这个函数不会去检测那些PATH环境变量的
schlafenhamster 2010-02-09
  • 打赏
  • 举报
回复
//// creating process
BOOL CMainFrame::GoCommand(char *command,BOOL fwait /* FALSE */)
{
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset (&sinfo,0,sizeof(STARTUPINFO));
sinfo.cb=sizeof(STARTUPINFO);
sinfo.dwFlags|=STARTF_USESHOWWINDOW;
sinfo.wShowWindow=SW_SHOWNORMAL;
//BOOL fsuccess=0;
BOOL fsuccess=CreateProcess(NULL,//lpApplicationName
command, //lpCommanderLine
NULL, //lpProcessAttributes
NULL, //lpThreadAttributes
FALSE, //bInheritHandles
NORMAL_PRIORITY_CLASS,//dwCreationFlags
NULL, //lpEnvironment
NULL, //lpCurrentDirectory
&sinfo, //lpStartupInfo
&pinfo); //lpProcessInformation
// wait for NotePad finishes
if(fsuccess)
{
HANDLE hProcess=pinfo.hProcess;
CloseHandle(pinfo.hThread);// close thread at once
if(fwait)
{
if (WaitForSingleObject(hProcess,INFINITE)!=WAIT_FAILED)
{
DWORD dwExitCode;
GetExitCodeProcess(hProcess,&dwExitCode);
// if (dwExitCode==STILL_ACTIVE) AfxMessageBox("Still Active");
}
}
CloseHandle(pinfo.hProcess);
}
return(fsuccess);
}
samuelo 2010-02-09
  • 打赏
  • 举报
回复
3楼正解。
看来系统如果在当前目录找不到cmd,不会自动去system32里找。
似乎与系统找文件的规则不符啊。
sjdev 2010-02-09
  • 打赏
  • 举报
回复
_T("c:\\windows\\system32\\cmd.exe")
samuelo 2010-02-09
  • 打赏
  • 举报
回复
改成TEXT( "/c c:\\zzz.bat" )也没用。。。。
wangk 2010-02-09
  • 打赏
  • 举报
回复
写错啦!
用TEXT( "/c c:\\zzz.bat" )还差不多

/c表示:执行字符串指定的命令然后退出

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧