Running another program in Windows bat file and not create child process
Asked Answered
D

7

21

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 child process exit, so using somthing like:

start another_prog...

in the hook bat file has no use.

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.

Dubonnet answered 8/10, 2009 at 7:40 Comment(2)
Can you clarify what problem you are trying to solve? Is it really the case that the subversion post-commit hook waits for all processes to exit? why doesn't start cmd /c startWebLogic.cmd work?Doenitz
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: svn.haxx.se/users/archive-2008-11/0301.shtmlDubonnet
D
14

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.

#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; 
} 
Dubonnet answered 17/10, 2009 at 13:20 Comment(3)
Millions thanks for the right solution! It is still little bit uncomfortable to create your own program to execute some other program. However, 100 times better then using scheduled tasks and so on. Thx thx thxTerni
Here is a link to a compiled executable of the source code: mega.nz/#!u8tD0YAY!OuULXWhzG4VThwLAbkjpRdTfg6XLgxFmmpNP2hnzb1wBonus
how about making some provision to supply command line arguments to another_prog? otherwise, i'd have to involve wrapping another batch script around invoking the exe with the argsQuiteria
L
28

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

EDIT: The following comment was made elsewhere by @zhongshu, the original poster. I'm only copying it here:

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

Assuming that he knows what he's talking about, I'm wrong and...undeserving.

Lanceted answered 15/10, 2009 at 2:0 Comment(1)
Reversed: If you want to open/run 100 bat/cmd processes (like me) and make them be a child process of the parent process (e.g. for easy closing) - put commands into a bat/cmd and start it from another bat/cmd (not by double-clicking). I wrote this because I was googling the reversed intention and haven't found anything.Polycarp
D
14

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.

#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; 
} 
Dubonnet answered 17/10, 2009 at 13:20 Comment(3)
Millions thanks for the right solution! It is still little bit uncomfortable to create your own program to execute some other program. However, 100 times better then using scheduled tasks and so on. Thx thx thxTerni
Here is a link to a compiled executable of the source code: mega.nz/#!u8tD0YAY!OuULXWhzG4VThwLAbkjpRdTfg6XLgxFmmpNP2hnzb1wBonus
how about making some provision to supply command line arguments to another_prog? otherwise, i'd have to involve wrapping another batch script around invoking the exe with the argsQuiteria
I
8

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:

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.

Indemnify answered 15/10, 2009 at 21:49 Comment(1)
This works really well for the SVN Post commit on windows. We were using a Powershell script which caused a noticable delay with any commit to svn. Now with the scheduled task, the commit finishes immediately and the task executes in the background. schtasks /run /tn NameOfTask is the best solution here.Elle
T
6

Use:

start cmd /c "your command"

Cheers.

Toenail answered 12/10, 2009 at 2:18 Comment(2)
In many cases you should be able to omit the "cmd /c" (see answer by Corey Trager)Eubanks
This will not work for SVN post-commit hook on Windows. It will still wait for the child process to complete. See Corey Trager's answerElle
S
1

Try cmd /c "your command"

Southern answered 8/10, 2009 at 7:43 Comment(1)
No, cmd /c has no use, svn will wait the "your command" finish.Dubonnet
M
1

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.

Miltiades answered 12/10, 2009 at 1:59 Comment(0)
W
0

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_prog in detached mode with shell.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));`
Weirick answered 8/3, 2017 at 20:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.