在 Windows bat 文件中运行另一个程序而不创建子进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1536205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running another program in Windows bat file and not create child process
提问by zhongshu
I have subversion server with a post-commit hook to do something.
我有一个带有提交后钩子的颠覆服务器来做一些事情。
I want the checkin finish soon, not wait the hook script. But by design, the Subversion post-commit hook script will run until all childprocess exit, so using somthing like:
我希望签入尽快完成,而不是等待钩子脚本。但是按照设计,Subversion post-commit 钩子脚本将运行直到所有子进程退出,所以使用类似的东西:
start another_prog...
启动另一个_程序...
in the hook bat file has no use.
在 hook bat 文件中没有用。
So I want to know how to run another program in Windows bat file which not create child process or let the child process detach from the parent.
所以我想知道如何在 Windows bat 文件中运行另一个程序,该程序不创建子进程或让子进程与父进程分离。
采纳答案by zhongshu
I found a method to resolve my question, compile the following c code and named the exe output as runjob.exe, and then in the hook bat file, use " runjob another_prog " , now it's ok.
我找到了解决我的问题的方法,编译下面的c代码并将exe输出命名为runjob.exe,然后在hook bat文件中,使用“runjob another_prog”,现在就可以了。
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int _tmain()
{
char * pCmd = ::GetCommandLine();
// skip the executable
if (*pCmd++ == L'"')
{
while (*pCmd++ != L'"');
}
else
{
while (*pCmd != NULL && *pCmd != L' ')
++pCmd;
}
while (*pCmd == L' ')
pCmd++;
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
BOOL result = CreateProcess
(
NULL, // No module name (use command line)
pCmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set bInheritHandles to FALSE
DETACHED_PROCESS, // Detach process
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (returned)
);
if (result) return 0;
char msg[2048];
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
msg, sizeof(msg),
NULL
);
fputs(msg, stderr);
_flushall();
return -1;
}
回答by Corey Trager
Synchronous. The second notepad won't launch until you close the first.
同步。在您关闭第一个记事本之前,第二个记事本不会启动。
notepad.exe c:\temp\a.txt
notepad.exe c:\temp\b.txt
Asynchronous: The second notepad will launch even if you haven't closed the first.
异步:即使您没有关闭第一个记事本,第二个记事本也会启动。
start notepad.exe c:\temp\a.txt
start notepad.exe c:\temp\b.txt
More info about the start command:
http://www.robvanderwoude.com/ntstart.php
有关启动命令的更多信息:http:
//www.robvanderwoude.com/ntstart.php
EDIT: The following comment was made elsewhere by @zhongshu, the original poster. I'm only copying it here:
编辑:以下评论是由原始海报@zhongshu 在别处发表的。我只是复制到这里:
start cmd /c doesn't work because SVN post-commit hook will wait for the hook and the child process created by the hook exit. It's the design of SVN. I have found a solution, Please refer: http://svn.haxx.se/users/archive-2008-11/0301.shtml
start cmd /c 不起作用,因为 SVN post-commit 钩子将等待钩子和钩子创建的子进程退出。这是SVN的设计。我找到了解决方案,请参考:http: //svn.haxx.se/users/archive-2008-11/0301.shtml
Assuming that he knows what he's talking about, I'm wrong and...undeserving.
假设他知道他在说什么,我错了,而且……不配。
回答by jasonh
What you can do is create a Scheduled Task that executes the batch script or other executable that runs for a long time. Set it to run once, in the past and don't set it to delete the task when no more runs are scheduled. Then in your Subversion hook script, put the following line in:
您可以做的是创建一个计划任务来执行批处理脚本或其他长时间运行的可执行文件。将其设置为过去运行一次,并且不要将其设置为在不再安排运行时删除任务。然后在您的 Subversion 钩子脚本中,输入以下行:
schtasks /run /tn NameOfYourTaskHere
I confirmed with a test by having my scheduled task run Notepad++ and the Notepad++ executable showed up as a child of svchost.exe, not the cmd.exe window that I executed the schtasks
command from.
我通过让我的计划任务运行 Notepad++ 进行了测试,并且 Notepad++ 可执行文件显示为 svchost.exe 的子项,而不是我schtasks
从中执行命令的 cmd.exe 窗口。
回答by OJ.
Use:
用:
start cmd /c "your command"
Cheers.
干杯。
回答by lsiu
Try cmd /c "your command"
尝试 cmd /c "your command"
回答by SqlACID
Could you use the windows task scheduler command line interface "schtasks /run" to start a job that runs the "another_prog"? You'd have to create the job ahead of time. There also used to be a "SOON" program with the Windows (NT) Resource Kit that would create dynamic entries for the "AT" command scheduler to run a job in a few minutes that would not require setting up a job ahead of time, it can still be found with a little searching.
您能否使用 Windows 任务调度程序命令行界面“schtasks /run”来启动运行“another_prog”的作业?您必须提前创建作业。曾经还有一个带有 Windows (NT) Resource Kit 的“SOON”程序,它可以为“AT”命令调度程序创建动态条目,以便在几分钟内运行不需要提前设置作业的作业,它仍然可以通过一些搜索找到。
回答by dlauzon
You can create a hybrid batch/JScript file (i.e. a batch file able to run embedded JScript) where the JScript part will run another_progin detached mode with shell.Run(prog, 0, false):
您可以创建一个混合批处理/JScript 文件(即能够运行嵌入式 JScript 的批处理文件),其中 JScript 部分将使用shell.Run(prog, 0, false)在分离模式下运行another_prog:
@if (@X)==(@Y) @end /* JScript comment
rem put any batch code that runs before another_prog here
@cscript //E:JScript //nologo "%~f0" "another_prog" 0 false
rem put any batch code that runs after another_prog here
exit /b %errorlevel%
@if (@X)==(@Y) @end JScript comment */
var ARGS = WScript.Arguments;
var shell = new ActiveXObject("WScript.Shell");
shell.Run(ARGS.Item(0),ARGS.Item(1),ARGS.Item(2));`