Завершение работы системы () через определенное время в Windows - PullRequest
5 голосов
/ 29 января 2012

Я запускаю приложение командной строки из скрипта perl (с использованием system ()), которое иногда не возвращает, а точнее выдает исключение, которое требует ввода данных пользователем для прерывания приложения. Этот скрипт используется для автоматического тестирования приложения, которое я запускаю с помощью команды system (). Поскольку это часть автоматизированного тестирования, команда sytem () должна возвращаться, если возникает исключение, и считать тест неудачным.

Я хочу написать фрагмент кода, который запускает это приложение, и, если возникает исключение, он должен продолжить работу со сценарием, считая этот тест неудачным.

Один из способов сделать это - запустить приложение в течение определенного периода времени, и если системный вызов не возвращается в течение этого периода времени, мы должны завершить system () и продолжить выполнение сценария. ( Как я могу завершить системную команду с тревогой в Perl? )

код для достижения этого:

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

но этот код не работает в Windows, я провел некоторое исследование по этому вопросу и обнаружил, что SIG не работает в Windows (программирование на языке Perl). Кто-нибудь может подсказать, как я могу добиться этого в Windows?

Ответы [ 2 ]

6 голосов
/ 29 января 2012

Я бы порекомендовал посмотреть на модуль Win32 :: Process . Это позволяет вам запустить процесс, подождать его некоторое время и даже при необходимости убить его. Исходя из примера, приведенного в документации, все выглядит довольно просто:

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
}

Вы также можете спать в течение соответствующего количества секунд и использовать метод kill в этом модуле. Я не совсем уверен, хотите ли вы использовать флаг создания NORMAL_PRIORITY_CLASS; документация для этого модуля довольно плохая. Я вижу некоторые примеры использования флага DETACHED_PROCESS. Вам придется поиграть с этой частью, чтобы увидеть, что работает.

1 голос
/ 29 января 2012

См. Proc :: Background , абстрагирует код для win32 и linux, функция timeout_system( $seconds, $command, $arg, $arg, $arg )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...