2012-01-29 10 views
5

Używam aplikacji wiersza poleceń z poziomu skryptu perl (przy użyciu system()), który czasami nie zwraca, a mówiąc dokładniej, zgłasza wyjątek, który wymaga dane wprowadzane przez użytkownika w celu przerwania aplikacji. Ten skrypt służy do automatycznego testowania uruchomionej aplikacji za pomocą polecenia system(). Ponieważ jest to część testów automatycznych, polecenie sytem() musi zwrócić, jeśli wystąpi wyjątek i uznać test za niepowodzenie.Kończenie systemu() po pewnym czasie w systemie Windows

Chcę napisać fragment kodu uruchamiającego tę aplikację, a jeśli wystąpi wyjątek, należy kontynuować ze skryptem, uważając, że ten test nie powiódł się.

Jednym ze sposobów, aby to zrobić, jest uruchomienie aplikacji przez pewien okres czasu i jeśli wywołanie systemowe nie powróci w tym okresie czasu, powinniśmy zakończyć system() i kontynuować działanie skryptu. (How can I terminate a system command with alarm in Perl?)

kod

do osiągnięcia tego celu:

my @output; 
eval { 
    local $SIG{ALRM} = sub { die "Timeout\n" }; 
    alarm 60; 
    return = system("testapp.exe"); 
    alarm 0; 
}; 
if ([email protected]) { 
    print "Test Failed"; 
} else { 
    #compare the returned value with expected 
} 

ale ten kod nie działa na windows zrobiłem kilka badań na ten temat i okazało się, że SIG nie działa na Windows (programowanie książki Perl). Czy ktoś może zasugerować, w jaki sposób mogę to osiągnąć w oknach?

Odpowiedz

6

Polecam, patrząc na moduł Win32::Process. Pozwala na rozpoczęcie procesu, czekanie na niego przez pewien zmienny okres czasu, a nawet zabicie go w razie potrzeby. Opierając się na przykład dokumentacja przewiduje, że wygląda całkiem proste:

use Win32::Process; 
use Win32; 

sub ErrorReport{ 
    print Win32::FormatMessage(Win32::GetLastError()); 
} 

Win32::Process::Create($ProcessObj, 
         "C:\\path\\to\\testapp.exe", 
         "", 
         0, 
         NORMAL_PRIORITY_CLASS, 
         ".")|| die ErrorReport(); 

if($ProcessObj->Wait(60000)) # Timeout is in milliseconds 
{ 
    # Wait succeeded (process completed within the timeout value) 
} 
else 
{ 
    # Timeout expired. $! is set to WAIT_FAILED in this case 
} 

Można też spać na odpowiednią liczbę sekund i użyć metody kill w tym module. Nie jestem do końca pewien, czy flaga tworzenia NORMAL_PRIORITY_CLASS jest tą, której chcesz użyć; dokumentacja tego modułu jest dość zła. Widzę kilka przykładów przy użyciu flagi DETACHED_PROCESS. Będziesz musiał bawić się tą częścią, aby zobaczyć, co działa.

+0

Thanks a lot! To działa :) – int80h

Powiązane problemy