/ / Jak poradzić sobie z wywołaniem „systemowym”, które kończy się niepowodzeniem? - Windows, Perl, obsługa błędów, zewnętrzne

Jak mogę obsłużyć wywołanie `system`, które nie działa? - okna, perl, obsługa błędów, zewnętrzne

Mam skrypt Perla, który wywołuje program zewnętrzny. (Obecnie korzystam z backticksa, ale równie dobrze mogę go użyć system lub coś z cpan.) Czasami program zawiedzie, powodując, że system Windows utworzy okno dialogowe „(program zewnętrzny) przestał działać” z tekstem

System Windows szuka rozwiązania problemu ...

wkrótce zastąpiony przez

Problem spowodował, że program przestał działać poprawnie. Windows zamknie program i powiadomi cię, czy rozwiązanie jest dostępne.

Niestety, ten komunikat o błędzie zatrzymuje proces umierania, powodując, że Perl nie powraca, dopóki użytkownik (ja!) Nie kliknie „Anuluj” lub „Zamknij program”. Czy istnieje sposób na uniknięcie tego zachowania?

W moim przypadku dopuszczalnym jest awaria programu - działa on użytecznie, ale absolutnie nie jest konieczny. Ale ponieważ musi działać bez nadzoru, nie mogę zablokować pozostałej pracy programu.

Odpowiedzi:

3 dla odpowiedzi № 1

Problem z twoim obecnym podejściem polega na tym, że backticks & system blokuj podczas działania / zawieszania się programu zewnętrznego. Możliwe inne podejścia.

  • Używanie wątków i różnych modułów z Win32 rodzina zajęta - poczekaj na zakończenie procesu lub kliknij pole dialong. To prawdopodobnie przesada.
  • Użyj sygnału alarmowego lub zdarzenia, aby obudzić program, gdy program zewnętrzny „zareagował zbyt długo”.
  • Użyj modułu IPC, aby otworzyć program i monitorować jego postęp.
  • Jeśli nie potrzebujesz zwracanej wartości programu potomnego, STDOUT lub STDERR, simbabque exec opcja ma zaletę, ale jeśli chcesz zachować kontrolę nad procesem, spróbuj Win32::Process. Przydało mi się to przy wielu okazjach. Moduł wait metoda może być doskonałą alternatywą dla mojej sugestii Alarmu lub sugestii snu simabque z dodatkową korzyścią, że Twój program nie będzie spał dłużej niż jest to wymagane przez dziecko.

0 dla odpowiedzi nr 2

Jeśli nie musisz czekać na zakończenie działania zewnętrznego programu, możesz to zrobić exec zamiast system i nigdy nie powróci.

Zawsze możesz dodać sleep $n następnie, aby poczekać, aż program zewnętrzny teoretycznie się zakończy.

exec("maybe_dies.exe");
sleep 1; # make sure it does stuff before it dies, or not, or whatever...