logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[delphi] Jak zrestartować aplikację z poziomu kodu?

prokopcio 24 Mar 2018 17:21 1014 10
REKLAMA
  • #1 17124903
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    Jak w najprostszy sposób zrestartować aplikację z poziomu kodu tak jakby ją zamknąć i uruchomić ?
  • REKLAMA
  • REKLAMA
  • #3 17124947
    kaamil1984
    Poziom 13  
    Posty: 76
    Pomógł: 6
    Ocena: 12
    Musisz zrobić dodatkową mini aplikację którą uruchomisz tuż przed zamknięciem tej głównej.

    Musiała by ona poczekać aż proces główny sie zakończy i uruchomic go ponownie.
  • REKLAMA
  • #4 17125260
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    kaamil1984 napisał:
    Musisz zrobić dodatkową mini aplikację którą uruchomisz tuż przed zamknięciem tej głównej.

    Musiała by ona poczekać aż proces główny sie zakończy i uruchomic go ponownie.
    o to się martwiłem. :(
  • #5 17125274
    kaamil1984
    Poziom 13  
    Posty: 76
    Pomógł: 6
    Ocena: 12
    A czym tu się martwić? 5 minut roboty z pisaniem, 5 minut roboty z testowaniem.

    Jak martwisz się takimi rzeczami to co będzie jak trzeba będzie napisać jakiś skomplikowany program?
  • #6 17125367
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    Skomplikowane rzeczy takie muszą być a proste powinny być proste ;)

    znalazłem :
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    potrzebowałem tego do zakończenia aktualizacji firmware kontrolera po której najwygodniej przeładować program bo wiele rzeczy jest wykonywanych podczas startu programu, oczywiście da się to zrobić "lepiej" ale ja leniwy jestem więc wolałem użyć tych dwóch linijek kodu do restartu aplikacji.

    wszystko śmiga wyśmienicie.

    Natomiast sposób odpowiedzi na zadane pytanie jest żenujący.

    Dodano po 12 [minuty]:

    oczywiście można użyć zwykłego close, a w źródle projektu poczekać na zakończenie "poprzedniej aplikacji"...
  • #7 17125420
    katakrowa
    Poziom 23  
    Posty: 902
    Pomógł: 9
    Ocena: 855
    prokopcio napisał:
    potrzebowałem tego do zakończenia aktualizacji firmware kontrolera po której najwygodniej przeładować program bo wiele rzeczy jest wykonywanych podczas startu programu, oczywiście da się to zrobić "lepiej" ale ja leniwy jestem więc wolałem użyć tych dwóch linijek kodu do restartu aplikacji.
    wszystko śmiga wyśmienicie.


    Brawo! Wydrukuj sobie dyplom!
    Niestety tylko Ci się wydaje, że śmiga wyśmienicie. Szkoda, że nie doceniasz dobrych porad.
    Twój kod nie zawsze musi zadziałać ... I to co napisał kaamil1984 jest rozwiązaniem bardziej profesjonalnym i ogólniejszym.

    kaamil1984 napisał:
    Musisz zrobić dodatkową mini aplikację którą uruchomisz tuż przed zamknięciem tej głównej.
    Musiała by ona poczekać aż proces główny sie zakończy i uruchomić go ponownie.


    Taki "launcher" powinien poczekać aż odpalona aplikacja wyłączy się a dopiero po chwili powinien uruchomić ponownie EXE.
    Zauważ, że nie napisałeś co robi Twoja aplikacja być może to jakiś prosty program, nie korzystający z żadnych zasobów systemowych i rzeczywiście w tym specyficznym przypadku rozwiązanie działa. Ale ogólnie to jest ROZWIĄZANIE BŁĘDNE i absolutnie nie należy tak robić.

    Wystarczy pomyśleć, że aplikacja wykorzystuje porty szeregowe, których konfigurację masz w pliku lub korzystasz na wyłączność z plików do zapisywania logów...
    A ty odpalasz kolejną aplikację korzystającą z tych samych zasobów nie czekając aż poprzednia zostanie zamknięta i zasoby zostaną zwrócone "do systemu".
    Nie wspomnę o tym, że wywoływanie .terminate to ostateczność na wypadek "skopanej" aplikacji ponieważ w tym przypadku zwracanie używanych zasobów może nie być zrealizowane poprawnie.

    prokopcio napisał:
    Natomiast sposób odpowiedzi na zadane pytanie jest żenujący.


    Nie wiem... Myślę, że trochę pokory nie zaszkodzi ...

    Dodano po 17 [minuty]:

    prokopcio napisał:
    oczywiście można użyć zwykłego close, a w źródle projektu poczekać na zakończenie "poprzedniej aplikacji"...

    Można bardzo jestem jednak ciekaw jak byś to zrealizował ?
  • #8 17125622
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    Z których słów wnioskujesz, że nie doceniam porad ? Przeczytaj poradę JackaCz który oskarża mnie o niechlujstwo a jak słusznie zauważyłeś nie podałem szczegółów, jedynie zapytałem jak prosto zrestartować aplikację...
    Co do pokory i dyplomu - zauważ że napisałem w dziale Początkujący a nie " Dyplomiści Specjaliści".

    Zanim odpalę aplikację potrafię poczekać na zwolnienie zasobów po zwykłym close.
    Dla mnie to proste rozwiązanie się sprawdziło znakomicie i zamieściłem rozwiązanie - może komuś też się przyda.

    O poziomie pomocy początkującym na elektrodzie zmieniłem zdanie - kiedyś było tutaj milej.
  • #9 17125687
    katakrowa
    Poziom 23  
    Posty: 902
    Pomógł: 9
    Ocena: 855
    prokopcio napisał:
    Z których słów wnioskujesz, że nie doceniam porad ?


    z tych:
    prokopcio napisał:
    Natomiast sposób odpowiedzi na zadane pytanie jest żenujący.


    Nie widzę niż żenującego w odpowiedzi:
    kaamil1984 napisał:
    Musisz zrobić dodatkową mini aplikację którą uruchomisz tuż przed zamknięciem tej głównej.
    Musiała by ona poczekać aż proces główny sie zakończy i uruchomic go ponownie.


    prokopcio napisał:
    Zanim odpalę aplikację potrafię poczekać na zwolnienie zasobów po zwykłym close.

    Niestety samo .close nie zwalnia wszystkich zasobów ... Nadal poruszasz się jedynie w zakresie przypadku Twojej aplikacji.
    Cieszę się, że program Ci zadziałał jednak musisz wiedzieć, że w ogólności jest to błędne rozwiązanie i nie należy go "promować".
    Jest to rozwiązanie, które zadziała w pewnych ściśle określonych okolicznościach i tyle ...
  • REKLAMA
  • #10 17125711
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    bo ja do Jacka pisałem :), tak masz rację odpowiedź kamila jest w porządku.
    przed zapytaniem myślałem o napisaniu drugiej aplikacji odpalanej z pierwszej a ta druga odpali pierwszą ale wydało mi się przerostem formy nad treścią dlatego zapytałem o prosty sposób. Co do close - zależy co jest w onClose zawarte, zakładam że to co być powinno :)
  • #11 17125790
    kaamil1984
    Poziom 13  
    Posty: 76
    Pomógł: 6
    Ocena: 12
    Jak chcesz żeby to było zrobione jak należy to zrób coś w tym rodzaju:

    1. Proces główny uruchamia proces pomocniczy z parametrem w którym znajduje się numer PID procesu głównego (systemowy Process Id).

    2. Proces główny robi close. Oczywiście nie dzieje się to natychmiast. W zależności od tego jakich zasobów uzywał - wykonanie destruktorow na wszystkich obiektach może chwilę potrwać i dlatego nie można od razu uruchamiać nowego procesu. Nawet gdyby cos takiego Ci zadziałało, to na innym komputerze może sie nie zdążyć zamknąć. Albo dopiszesz coś w kodzie za kilka dni i zamykanie procesu sie wydłuży.

    3. Proces pomocniczy w jakiejś pętli (najprostsze i wystarczająco dobre rozwiazanie) sprawdza np. co 100ms czy istnieje jeszcze proces z PID otrzymanym w parametrze. Nie wiem jak się to robi w Delphi. W ostatecznosci mozna przez cmd wyciągnąć listę procesów Windows. Dzięki parametrowi PID proces pomocniczy bedzie wiedział ktory proces zamknąć. Pozornie łatwiej było by to zrobić po nazwie procesu i po prostu szukac nazwaaplikacji.exe, ale to nie jest mądre rozwiązanie, bo jakiemuś uzytkownikowi, a moze nawet Tobie przy jakiejs okazji aktualizacji programu za rok można przyjsc do glowy żeby zmienić nazwę pliku exe i wtedy wszystko przestanie działać. Kto by sie mogł spodziewać, ze zmiana nazwy pliku exe moze popsuć mechanizm aktualizacji, no nie?

    Dodano po 18 [minuty]:

    Odpalanie nowego procesu zanim zamknie się poprzedni nie jest za dobrym pomysłem, ale jeżeli nad tym panujesz to ok. Upewnij sie tylko ze masz zasoby typu porty COM pozamykane jezeli jest to aplikacja z jakąś komunikacją po rs232, bo nowy proces nie będzie mógł się do nich dostać przez chwilę. Podobnie z plikami otwartymi w trybie wyłączności.

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono temat restartowania aplikacji w Delphi z poziomu kodu. Użytkownik zapytał o najprostszy sposób na zamknięcie i ponowne uruchomienie aplikacji. Odpowiedzi sugerowały różne podejścia, w tym użycie funkcji ShellExecute do uruchomienia aplikacji po jej zamknięciu oraz stworzenie dodatkowej aplikacji pomocniczej, która monitorowałaby zakończenie procesu głównego. Podkreślono, że proste rozwiązania mogą nie zawsze być odpowiednie, zwłaszcza w przypadku aplikacji korzystających z zasobów systemowych. Wskazano na konieczność odpowiedniego zarządzania zasobami, aby uniknąć problemów z ich zwalnianiem.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA