2009-10-08 10 views
14

J'ai un serveur subversion avec un crochet post-commit pour faire quelque chose.Exécution d'un autre programme dans Windows fichier bat et pas de créer un processus enfant

Je veux que le checkin se termine bientôt, ne pas attendre le script de crochet. Mais par la conception, le script de post-commit hook Subversion fonctionnera jusqu'à ce que toute la sortie du processus enfant, donc en utilisant somthing comme:

début another_prog ...

dans le fichier de chauve-souris crochet n'a pas utilisé.

Donc je veux savoir comment exécuter un autre programme dans le fichier bat Windows qui ne crée pas de processus fils ou laisse le processus fils se détacher du parent.

+0

Pouvez-vous clarifier quel problème vous essayez de résoudre? Est-ce vraiment le cas que le hook post-commit de subversion attende que tous les processus soient sortis? pourquoi "ne démarre pas cmd/c startWebLogic.cmd" fonctionne-t-il? – Cheeso

+4

start cmd/c ne fonctionne pas car le hook SVN post-commit attendra le hook et le processus ** child ** créé par la sortie du hook. C'est la conception de SVN. J'ai trouvé une solution, S'il vous plaît se référer: http://svn.haxx.se/users/archive-2008-11/0301.shtml – zhongshu

Répondre

12

J'ai trouvé une méthode pour résoudre ma question, compiler le code c suivant et nommé la sortie exe comme runjob.exe, puis dans le fichier hook bat, utilisez "runjob another_prog", maintenant c'est 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; 
} 
+0

Des millions de mercis pour la bonne solution! Il est encore un peu mal à l'aise de créer votre propre programme pour exécuter un autre programme. Cependant, 100 fois mieux alors en utilisant des tâches planifiées et ainsi de suite. Thx thx thx – Honzajscz

+3

Voici un lien vers un exécutable compilé du code source: https://mega.nz/#!u8tD0YAY!OuULXWhzG4VThwLAbkjpRdTfg6XLgxFmmpNP2hnzb1w –

+1

que diriez-vous de faire une provision pour fournir des arguments de ligne de commande à 'another_prog'? sinon, je devrais impliquer d'encapsuler un autre script batch en invoquant l'exe avec les arguments – evandrix

0

Essayez de cmd /c "your command"

+1

Non, cmd/c ne sert à rien, svn attendra la fin de votre "commande". – zhongshu

1

Pouvez-vous utiliser les tâches de Windows interface de ligne de commande programmateur « schtasks/run » pour démarrer un travail qui exécute le « another_prog »? Vous devez créer le travail à l'avance. Il y avait également un programme "SOON" avec le Kit de Ressources Windows (NT) qui créerait des entrées dynamiques pour le planificateur de commandes "AT" pour exécuter un travail en quelques minutes qui ne nécessiterait pas de configurer un travail à l'avance, il peut encore être trouvé avec un peu de recherche.

3

Utilisation:

start cmd /c "your command" 

Vive.

+0

Dans de nombreux cas, vous devriez être en mesure d'omettre le "cmd/c" (voir la réponse par Corey Trager) – jdigital

+0

Cela ne fonctionnera pas pour le post-commit SVN sur Windows. Il attendra toujours que le processus enfant se termine. Voir [la réponse de Corey Trager] (http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process/1569941#1569941) – truemedia

16

Synchrone. Le second bloc-notes ne sera pas lancé tant que vous ne fermerez pas le premier. Asynchrone: Le second bloc-notes sera lancé même si vous n'avez pas fermé le premier.

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

Plus d'informations sur la commande de démarrage:
http://www.robvanderwoude.com/ntstart.php

EDIT: Le commentaire suivant a été fait par ailleurs @zhongshu, l'affiche originale. Je ne copie ici:

démar/c ne fonctionne pas parce que SVN post-commit hook attendra le crochet et le processus de l'enfant créé par la sortie du crochet. C'est la conception de SVN. J'ai trouvé une solution, S'il vous plaît se référer: http://svn.haxx.se/users/archive-2008-11/0301.shtml

En supposant qu'il sait de quoi il parle, je me trompe et ... ne mérite pas.

5

Ce que vous pouvez faire est de créer une tâche planifiée qui exécute le script de traitement par lots ou un autre exécutable qui s'exécute depuis longtemps. Réglez-le pour exécuter une fois, dans le passé et ne le définissez pas pour supprimer la tâche lorsque plus d'exécutions sont planifiées. Ensuite, dans votre script hook Subversion, mettez la ligne suivante dans:

schtasks /run /tn NameOfYourTaskHere 

Je confirme avec un test en ayant ma course de tâche planifiée Notepad ++ et l'exécutable Notepad ++ a montré comme un enfant de svchost.exe, pas le cmd.fenêtre exe que j'ai exécuté la commande schtasks de.

+0

Cela fonctionne vraiment bien pour le commit SVN Post sur Windows. Nous utilisions un script Powershell qui causait un retard notable avec tout commit à svn. Maintenant, avec la tâche planifiée, la validation se termine immédiatement et la tâche s'exécute en arrière-plan. 'schtasks/run/tn NameOfTask' est la meilleure solution ici. – truemedia

0

Vous pouvez créer un fichier batch hybride/JScript (par exemple un fichier batch capable d'exécuter JScript intégré) où la partie JScript se déroulera another_prog en mode détaché avec 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));` 
Questions connexes