【问题标题】:Running another program in Windows bat file and not create child process在 Windows bat 文件中运行另一个程序并且不创建子进程
【发布时间】:2009-10-08 07:40:03
【问题描述】:

我有一个带有提交后挂钩的颠覆服务器来做某事。

我希望签入尽快完成,而不是等待挂钩脚本。 但是按照设计,Subversion 提交后挂钩脚本将一直运行,直到所有 child 进程退出,所以使用类似:

启动另一个程序...

在钩子bat文件中没有用。

所以我想知道如何在 Windows bat 文件中运行另一个程序,它不会创建子进程或让子进程与父进程分离。

【问题讨论】:

  • 您能说明您要解决的问题吗?真的是subversion post-commit钩子等待所有进程退出吗?为什么start cmd /c startWebLogic.cmd 不起作用?
  • start cmd /c 不起作用,因为 SVN 提交后挂钩将等待挂钩和挂钩退出创建的 child 进程。这是SVN的设计。我找到了解决办法,请参考:svn.haxx.se/users/archive-2008-11/0301.shtml

标签: windows batch-file svn svn-hooks post-commit


【解决方案1】:

同步。在您关闭第一个记事本之前,第二个记事本不会启动。

notepad.exe c:\temp\a.txt
notepad.exe c:\temp\b.txt

异步:即使您没有关闭第一个记事本,第二个记事本也会启动。

start notepad.exe c:\temp\a.txt
start notepad.exe c:\temp\b.txt

更多关于启动命令的信息:
http://www.robvanderwoude.com/ntstart.php

编辑:以下评论由原发帖者@zhongshu 在别处发表。我只是在这里复制它:

start cmd /c 不起作用,因为 SVN post-commit 钩子将等待 钩子和创建的子进程 钩子出口。这是SVN的设计。 我找到了解决办法,请参考: http://svn.haxx.se/users/archive-2008-11/0301.shtml

假设他知道自己在说什么,我错了,而且……不值得。

【讨论】:

  • 逆向:如果你想打开/运行 100 个 bat/cmd 进程(像我一样)并使它们成为父进程的子进程(例如,为了方便关闭) - 将命令放入 bat/ cmd 并从另一个 bat/cmd 启动它(不是通过双击)。我写这个是因为我在谷歌上搜索了相反的意图并且没有找到任何东西。
【解决方案2】:

我找到了解决问题的方法,编译如下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; 
} 

【讨论】:

  • 数百万感谢您提供正确的解决方案!创建自己的程序来执行其他程序仍然有点不舒服。但是,比使用计划任务等要好 100 倍。 thx thx thx
  • 这里是源代码的编译可执行文件的链接:mega.nz/#!u8tD0YAY!OuULXWhzG4VThwLAbkjpRdTfg6XLgxFmmpNP2hnzb1w
  • 如何为another_prog 提供命令行参数?否则,我将不得不在使用 args 调用 exe 时包装另一个批处理脚本
【解决方案3】:

您可以做的是创建一个计划任务来执行批处理脚本或其他长时间运行的可执行文件。将其设置为过去运行一次,并且不要将其设置为在不再安排运行时删除任务。然后在您的 Subversion 挂钩脚本中,输入以下行:

schtasks /run /tn NameOfYourTaskHere

我通过测试确认,让我的计划任务运行 Notepad++,并且 Notepad++ 可执行文件显示为 svchost.exe 的子项,而不是我执行 schtasks 命令的 cmd.exe 窗口。

【讨论】:

  • 这对于 Windows 上的 SVN Post 提交非常有效。我们使用了一个 Powershell 脚本,该脚本在任何提交到 svn 时都会导致明显的延迟。现在使用计划任务,提交立即完成,任务在后台执行。 schtasks /run /tn NameOfTask 是这里最好的解决方案。
【解决方案4】:

用途:

start cmd /c "your command"

干杯。

【讨论】:

  • 在许多情况下,您应该能够省略“cmd /c”(参见 Corey Trager 的回答)
  • 这不适用于 Windows 上的 SVN 提交后挂钩。它仍然会等待子进程完成。见Corey Trager's answer
【解决方案5】:

试试cmd /c "your command"

【讨论】:

  • 不行,cmd /c 没有用,svn 会等待“你的命令”完成。
【解决方案6】:

您可以使用 Windows 任务调度程序命令行界面“schtasks /run”来启动运行“another_prog”的作业吗?您必须提前创建工作。曾经还有一个带有 Windows (NT) 资源工具包的“SOON”程序,它可以为“AT”命令调度程序创建动态条目,以便在几分钟内运行不需要提前设置作业的作业,稍微搜索一下还是可以找到的。

【讨论】:

    【解决方案7】:

    您可以创建一个混合批处理/JScript 文件(即能够运行嵌入式 JScript 的批处理文件),其中 JScript 部分将以分离模式运行 another_progshell.Run(prog, 0, false):

    @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));`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      相关资源
      最近更新 更多