Uruchomienie programu zewnętrznego

0

Witam
Mam problem z uruchomieniem programu zewnętrznego w python. Mam przycisk z którego wywołuję program. Trudność jest w tym jedna. Jeżeli kliknę dwa razy w przecisk program uruchomi się tylko raz. Każdorazowe kliknięcie w przycisk nie będzie miało żadnej reakcji pod warunkiem że program wywoływany jest uruchomiony. Jeżeli tak nie jest ma zostać ponownie wywołany program.
Samo wywołanie poprzez os nie jest dla mnie wystarczające. Dodam iż program wywoływany jest pisany w java a drugi w c++.
Proszę o pomoc.

0

Na początek rozwiązania brutalne:

Poszukaj w liście procesów czy już jest odpalony ( zakładam, że robisz to na jakimś linuxie a program uruchomiłeś komendami systemowymi nie przechwytując żadnego uchwytu do uruchomionej apki ).
Druga metoda uruchom program ze skryptu .sh, który czeka na jego zakończenie a w samym skrypcie zakładaj i kasuj flagi/tokeny np. w pliku informujące o tym, że program działa. Brutalne to i mało zgrabne ale czasem może być skuteczne.

Jeśli masz możliwość modyfikacji wywoływanych aplikacji to najlepiej gdyby z Twoją główną komunikowały się w jakiś ładniejszy sposób np. wykorzystując https://www.geeksforgeeks.org/ipc-using-message-queues/ lub coś analogicznego.

Masz też http://docs.python.org/library/subprocess.html

Niestety nie napisałeś co to za aplikację odpalasz i czy oczekujesz na jej zakończenie czy nie. Pokaż może sam kod, który ją odpala.

0

Właśnie program będzie uruchamiany po Windowsem i Linuxem, takie maszyny posiada klient niestety. Wywoływałem to w ten sposób:
os.system(configfile[1]+configfile[2]).
Parametry biorę z pliku ini. Ścieżka jest poprawna ponieważ program uruchamia się i od razu się wysypuje. W miejscu mojego programu wywoływany program potworzył pliki logu i pliki cache i wypisał że nie ma potrzebnych plików do działania. Wygląda to tak jak bym uruchamiał program z danej ścieżce a on szukał plików w moim programie. Ten program wywoływany nie jest mojego wykonania.

0

Na szybko napisałem takie wywołanie i jest identyczna sytuacja jak opisałem wyżej.
subprocess.Popen(configfile[1]+configfile[2], bufsize=-1)

0

A jesteś pewien na 100%, że wywoływany program uruchamia się w dobrym katalogu ? To, że podajesz ścieżkę do *.exe nie znaczy, że on się w niej wywoła. ustaw Przed wywołaniem świadomie zmień ścieżkę na odpowiednią os.chdir( 'c:\path do wywoływanego exe' ).

0

Faktycznie pomogło. Teraz muszę opanować jakoś jak zabezpieczyć przed dwukrotnym uruchomieniem aplikacji.

0
Masteratom napisał(a):

Faktycznie pomogło. Teraz muszę opanować jakoś jak zabezpieczyć przed dwukrotnym uruchomieniem aplikacji.

To pamiętaj jeszcze, żeby po wywołaniu programu przywrócić poprawną ścieżkę, w której pracuje Twój program bo za chwilę Twój program zacznie zapisywać pliki w katalogu tego wywoływanego exe'ka :-)

1

Ja bym to zrobił jakoś tak:
w ramach aplikacji odpal sobie osobny wątek, który będzie robił coś w tym stylu

while True:
   cmd = queue.get(block=True, timeout=None)
   subprocess.call(cmd, ... )
   queue.task_done()

Wciśnięcie przycisku w głównej aplikacji powinno tylko wrzucić do kolejki jakies zadanie.
Jeśli chcesz uniknąć "kolejkowania" wciśnięć, to ustaw dla kolejki maxsize = 1 i wkładaj z użyciem queue.put_nowait(...)

https://docs.python.org/3/library/queue.html
https://docs.python.org/3/library/subprocess.html

0

Kurcze mam problem z sprawdzaniem czy aplikacja jest uruchomiona. Program mój prawidłowo uruchamia zewnętrzną aplikację. Lecz jeśli drugi raz przycisnę przycisk wieszam moją aplikację a aplikacja zewnętrzna sie drugi raz uruchamia. Chciałbym uzyskać efekt taki by móc tylko raz uruchomić tylko jedną aplikacje na raz. W tej sytuacji jaką posiadam ile razy wcisnę przycisk tyle razy uruchom i się aplikacja.
Uruchamiam w taki sposób aplikację :
process = subprocess.Popen(configfile[2], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
następnie chcę oczekiwać na zamknięcie aplikacji:
process.wait()

0

Dlaczego nie mogę zabić procesu komendą:
self.process.kill()
A wywołuję program
self.process = subprocess.Popen(configfile[2], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Dostaję taki błąd:
QObject::~QObject: Timers cannot be stopped from another thread
^C[Finished in 8.6s with exit code 3221225786]
[path: C:\Program Files\Python38\Scripts;C:\Program Files\Python38;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C:\Program Files (x86)\Microsoft SQL Server\150\DTS\Binn;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Users\dpalus\AppData\Local\Microsoft\WindowsApps]

0

Super dziękuję :) zadziałało prawidłowo z queue.get(). Wielkie dzięki :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1