2009-10-08 13 views
14

Tengo un servidor de subversión con un enlace post-commit para hacer algo.Ejecutar otro programa en el archivo bat de Windows y no crear el proceso secundario

Quiero que el checkin termine pronto, no espere la secuencia de comandos de gancho. Pero por diseño, el post-commit Subversion script gancho se ejecutará hasta que todo el proceso de salidaniño, por lo que usar algo como:

another_prog inicio ...

en el archivo gancho de murciélago tiene ninguna utilidad.

Así que quiero saber cómo ejecutar otro programa en el archivo bat de Windows que no crea un proceso hijo o deja que el proceso hijo se separe del padre.

+0

Puede usted aclara qué problema estás tratando de resolver ¿Es realmente el caso que el enganche post-commit de subversión espera a que salgan todos los procesos? ¿Por qué no funciona 'start cmd/c startWebLogic.cmd'? – Cheeso

+4

start cmd/c no funciona porque SVN post-commit hook esperará el hook y el proceso ** child ** creado por la salida hook. Es el diseño de SVN. He encontrado una solución, consulte: http://svn.haxx.se/users/archive-2008-11/0301.shtml – zhongshu

Respuesta

12

Encontré un método para resolver mi pregunta, compilar el siguiente código c y denominé el resultado exe como runjob.exe, y luego en el archivo hook bat, uso "runjob another_prog", ahora está bien.

#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; 
} 
+0

¡Millones de gracias por la solución correcta! Todavía es un poco incómodo crear su propio programa para ejecutar otro programa. Sin embargo, 100 veces mejor que usar tareas programadas, etc. Thx thx thx – Honzajscz

+3

Aquí hay un enlace a un ejecutable compilado del código fuente: https://mega.nz/#!u8tD0YAY!OuULXWhzG4VThwLAbkjpRdTfg6XLgxFmmpNP2hnzb1w –

+1

¿Qué le parece hacer alguna provisión para suministrar argumentos de línea de comando a 'another_prog'? de lo contrario, tendría que involucrar envolver otro script por lotes para invocar el exe con los argumentos – evandrix

0

Trate cmd /c "your command"

+1

No, cmd/c no tiene uso, svn esperará el final de "su comando". – zhongshu

1

Podría usar el comando programador de tareas de Windows interfaz de línea "schtasks/Ejecutar" para iniciar un trabajo que ejecuta el "another_prog"? Tendría que crear el trabajo antes de tiempo. También solía haber un programa "PRONTO" con el Kit de recursos de Windows (NT) que crearía entradas dinámicas para que el planificador de comandos "AT" ejecutara un trabajo en unos minutos que no requiriera configurar un trabajo antes de tiempo, todavía se puede encontrar con un poco de búsqueda.

3

Uso:

start cmd /c "your command" 

Saludos.

+0

En muchos casos, debe poder omitir el "cmd/c" (vea la respuesta de Corey Trager) – jdigital

+0

Esto no funcionará para el enganche post-commit de SVN en Windows. Todavía esperará a que se complete el proceso secundario. Véase [respuesta de Corey Trager] (http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process/1569941#1569941) – truemedia

16

Sincrónico. El segundo bloc de notas no se abrirá hasta que cierre el primero.

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

Asincrónico: El segundo bloc de notas se iniciará aunque no haya cerrado el primero.

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

Más información sobre el comando de arranque:
http://www.robvanderwoude.com/ntstart.php

EDITAR: El siguiente comentario fue hecho en otros lugares por @zhongshu, el cartel original. Sólo estoy copiando aquí:

cmd inicio/c no funciona porque SVN post-commit hook esperará a que el gancho y el proceso hijo creado por la salida gancho. Es el diseño de SVN. He encontrado una solución, por favor consulte: http://svn.haxx.se/users/archive-2008-11/0301.shtml

Suponiendo que él sabe lo que está hablando, yo estoy equivocado y ... no lo merecen.

5

Lo que puede hacer es crear una Tarea programada que ejecute el script por lotes u otro ejecutable que se ejecute durante un tiempo prolongado. Configúrelo para que se ejecute una vez, en el pasado y no lo configure para eliminar la tarea cuando no se programan más ejecuciones. Luego, en su script gancho de Subversion, poner la siguiente línea en:

schtasks /run /tn NameOfYourTaskHere 

Me confirmó con una prueba por tener mi programado Bloc de notas ejecución de la tarea ++ y el ejecutable Notepad ++ se presentó como un hijo de svchost.exe, no el cmd.ventana de exe que ejecuté el comando schtasks desde.

+0

Esto funciona muy bien para el commit SVN Post en Windows. Estábamos usando una secuencia de comandos Powershell que causó un retraso notable con cualquier compromiso con svn. Ahora con la tarea programada, la confirmación finaliza inmediatamente y la tarea se ejecuta en segundo plano. 'schtasks/run/tn NameOfTask' es la mejor solución aquí. – truemedia

0

Puede crear un archivo híbrido lotes/JScript (es decir, un archivo por lotes capaz de ejecutar JScript incrustado), donde la parte de JScript se ejecutará another_prog en modo independiente con 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));` 
Cuestiones relacionadas