我写了一个从命令提示符启动时工作良好的bat文件。现在我已经写了一个小的c++程序,使用CreateProcess从c++程序启动bat文件。c++程序接受2个命令行参数。一个是要执行的bat文件的路径,另一个是要写入bat文件输出的文件的路径。我像下面这样启动进程
DWORD processflags =
CREATE_DEFAULT_ERROR_MODE
//| CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
;
//security attribute
SECURITY_ATTRIBUTES securityAttr;
securityAttr.bInheritHandle = TRUE;
securityAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttr.lpSecurityDescriptor = NULL;
HANDLE fileHandleforChildProcessTowrite,fileHandleforChildProcessToRead, fileHandleforChildProcessToErr
fileHandleforChildProcessTowrite = CreateFile(logfilepath, FILE_SHARE_WRITE, 0, &securityAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//STARTUP INFO
STARTUPINFO sinfo;
ZeroMemory(&sinfo, sizeof(STARTUPINFO));
sinfo.cb = sizeof(STARTUPINFO);
sinfo.dwFlags = STARTF_USESTDHANDLES;
sinfo.hStdOutput = fileHandleforChildProcessTowrite;
sinfo.hStdInput = fileHandleforChildProcessToRead;
sinfo.hStdError = fileHandleforChildProcessToErr;
if (!CreateProcess(NULL, // No module name (use command line)
command, // bat file to be run
&securityAttr,
NULL,
TRUE, // Set handle inheritance to TRUE/FALSE
processflags, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&sinfo, // Pointer to STARTUPINFO structure
&pifo) // Pointer to PROCESS_INFORMATION structure
)
{
printf("CreateProcess failed (%d).n", GetLastError());
return PROCESS_CREATION_FAILED;
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
//Rest of the code follows to clean up logic to close process and file handles
我在这里面临的问题是,当我createProcess与bInheritHandles参数设置为FALSE批处理文件执行良好,但没有bat文件输出将写入文件句柄,这是预期的,但当我将bInheritHandles参数设置为TRUE bat文件执行失败,我在日志
中得到以下警告消息The process cannot access the file because it is being used by another process.
有人能帮我一下吗?为什么bat文件执行失败与bInheritHandles设置为TRUE,但工作良好,如果该标志是假的?由于显而易见的原因,我不能分享完整的bat文件,请原谅。
使用FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
作为CreateFile
API的dwShareMode
参数解决了这个问题
CreateFile(filehandlepate, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &secureAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);