CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Restart

Restart

dział ogólny

Re: Restart

Nowy postprzez polymorphism » wtorek, 14 grudnia 2010, 12:54

To, że działa, nie znaczy, że spełnia założenia. Równie dobrze możesz wywalić tę klasę, a za wywołaniem Close po prostu wstawić wywołania SetEvent i CloseHandle - efekt będzie dokładnie ten sam. Użycie tej klasy miało gwarantować to, że event przejdzie w stan signaled w momencie, gdy aplikacja zostanie zamknięta, tzn. wtedy, gdy wyskoczy z funkcji WinMain.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Darek_C++ » wtorek, 14 grudnia 2010, 13:51

Ja do restartu programu czyli jego zamkni ecia i ponownego uruchomienia używam takiego prostego kodu:
KOD cpp:     UKRYJ  
int h = Application->MessageBoxA("Wymagane jest ponowne uruchomienie programu", "Uwaga",mbNo);
if(h==1)
{
        Application->Terminate();
        Sleep(400);
        ShellExecute(Application->Handle, "open", Application->ExeName.c_str(), "-r", "", SW_SHOW);
        Beep(600, 100);

}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
        if(ParamStr(1) == "-r")
        {

                StatusBar1->Panels->Items[1]->Text = "Zrestartowano program";
        }
        else
        {
                StatusBar1->Panels->Items[1]->Text = "Gotowy";
        }
}
 
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Cyfrowy Baron » wtorek, 14 grudnia 2010, 14:00

I już na samym początku mam zastrzeżenie do Twojego kodu:

KOD cpp:     UKRYJ  
int h = Application->MessageBoxA("Wymagane jest ponowne uruchomienie programu", "Uwaga",mbNo);


Jeżeli przekazujesz tylko flagę mbNo, to masz do dyspozycji tylko opcję NIE. Poza tym do Application->MessageBox stosuje się zupełnie inne flagi. Ta której użyłeś jest stosowana raczej przy tworzeniu komunikatów np. za pomocą funkcji CreateMessageBox.
Tak to powinno wyglądać:

KOD cpp:     UKRYJ  
  int h = Application->MessageBoxA("Wymagane jest ponowne uruchomienie programu!\Czy chcesz restartować program?", "Uwaga", MB_YESNO | MB_ICONQUESTION);

 if(h == ID_YES)
 {
        Close();
        Sleep(400);

        ShellExecute(Application->Handle, "open", Application->ExeName.c_str(), L "", L"", SW_SHOW);

        Beep(600, 100);
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Darek_C++ » wtorek, 14 grudnia 2010, 15:12

Dlaczego close() [skoro to tyczy zamykania całej aplikacji], a nie Application->Terminate(); ?
Avatar użytkownika
Darek_C++
Elektrowied
Elektrowied
 
Posty: 454
Dołączył(a): piątek, 25 lipca 2008, 14:33
Podziękował : 66
Otrzymał podziękowań: 4
System operacyjny: Windows XP Pro SP2
Kompilator: Turbo Explorer C++
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Cyfrowy Baron » wtorek, 14 grudnia 2010, 21:51

Terminate odnosi się do wszystkich okien aplikacji, więc niezależnie od tego z którego okna wywołasz tą funkcje, to zamknięta zostanie cała aplikacja. Close zamyka tylko okno dla którego została ta funkcja wywołana, jeżeli jest to okno główne aplikacji to zamknięta zostanie cała aplikacja ze wszystkimi oknami.

Close zwalnia wszystkie zasoby aplikacji przed zamknięciem, a Terminate zabija proces i pozostawia w pamięci śmieci po aplikacji. Terminate zamyka bezwarunkowo aplikację i powinno się jej używać tylko gdy w aplikacji istnieje ryzyko wystąpienia błędów i nie da się zakończyć jej działania funkcją Close.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez polymorphism » wtorek, 14 grudnia 2010, 22:52

Cyfrowy Baron napisał(a):(...) a Terminate zabija proces i pozostawia w pamięci śmieci po aplikacji.

Nic z tych rzeczy. Terminate wysyła komunikat WM_QUIT, co powoduje, że aplikacja zostaje zamknięta w ten sam sposób, jakbyś zamknął jej główne okno. Pomyliłeś tę metodę z funkcją TerminateThread.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Pitek » środa, 15 grudnia 2010, 00:37

Wszystko działa z poprawionym kodem od polimorphism ale dalej pojawia się to o czym mówiłem jeżeli od otwarcia programu do restartu wykonam jakieś działanie to restart nie spełnia swojej funkcji tylko zamyka program. Natomiast jeżeli od otwarcia programu nie robię nic tylko od razu go restartuje to jest ok. Czemu się tak dzieje jaki kod mam pokazać gdzie mogę robić błąd ?
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Restart

Nowy postprzez polymorphism » środa, 15 grudnia 2010, 11:09

KOD cpp:     UKRYJ  
String nazwa = ExtractFileName(Application->ExeName);

...

        ShellExecute(NULL,"open",(nazwa).t_str(),NULL,NULL,SW_SHOW);
 

Nigdy nie podawaj względnych ścieżek, jeśli nie masz pewności co do aktualnego katalogu.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Cyfrowy Baron » środa, 15 grudnia 2010, 12:11

Czyli powinieneś zrobić to tak:

KOD cpp:     UKRYJ  
ShellExecute(NULL, NULL, Application->ExeName.t_str(),NULL,NULL,SW_SHOW);


Co zresztą podałem w swoim kodzie.



polymorphism napisał(a):Nic z tych rzeczy. Terminate wysyła komunikat WM_QUIT, co powoduje, że aplikacja zostaje zamknięta w ten sam sposób, jakbyś zamknął jej główne okno.


Sugerowałem się tym fragmentem z pliku pomocy:


By calling Terminate rather than freeing the application object, you allow the application to shut down in an orderly fashion.




Jak rozumiem zamiast zwalniania obiektów aplikacji pozwala zamknąć... i to orderly fashion jest dla mnie trochę niezrozumiałe - sposób uporządkowany, ale co to oznacza.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez polymorphism » środa, 15 grudnia 2010, 12:40

To 'in orderly fashion' rozumiem jako 'we właściwy sposób'. I nie 'obiektów aplikacji', tylko 'application object', co ja przetłumaczyłem jako 'obiekt Application'.

Czyli całe zdanie przetłumaczyłbym tak:

    Wywołując Terminate zamiast usuwać obiekt Application, zamykasz aplikację we właściwy sposób.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Cyfrowy Baron » środa, 15 grudnia 2010, 12:42

Co to jednak oznacza: zamiast usuwać obiekt Application?
Poza tym Close(), też zamyka aplikację prawidłowo, więc w czym tkwi różnica?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez polymorphism » środa, 15 grudnia 2010, 13:01

Co to jednak oznacza: zamiast usuwać obiekt Application?

Domyślam się, że chodzi np. o to:
KOD cpp:     UKRYJ  
Application->Free();
// lub
delete Application;



(...) więc w czym tkwi różnica?

W tym, że Close zamyka konkretne okno, a Terminate zamyka całą aplikację. Jak łatwo się domyśleć, zamknięcie głównego okna aplikacji w konsekwencji spowoduje wywołanie metody Terminate (lub kodu, który robi to samo).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez Pitek » środa, 15 grudnia 2010, 19:03

Bardzo dziękuję wersja bez zmiennej pośredniczącej działa dobrze. Mam jednak jeszcze pytanie jak do tej aktualnej funkcji stworzyć coś co by się z nią nie gryzło i dobrze działało a chodzi mi o blokadę ponownego uruchomienia bo ta blokada o której już tutaj wspomniano wyrzuca przy próbie restartu że nie można uruchomić kopii czyli nie pozwala na restart.
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Restart

Nowy postprzez Cyfrowy Baron » środa, 15 grudnia 2010, 19:37

Ja rozwiązałem ten problem stosując metodę zaproponowaną przez polymorphism. Czyli w klasie restartu nic nie zmieniam, jednak przed dokonaniem restartu zmieniam nazwę okna głównego. Mutex za pomocą funkcji FindWindow szuka programu po nazwie klasy i nazwie okna. Gdy restart zmieni nazwę okna, to mutex nie może go odnaleźć i restartuje okno, natomiast bez restartu nie można uruchomić kopii programu, gdyż mutex to blokuje:

W pliku Project.cpp
KOD cpp:     UKRYJ  
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
 HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, L"Project1.exe_mutex");
 if(!hMutex) hMutex = CreateMutex(0, 0, L"Project1.exe_mutex");
 else
  {
   HWND hWnd = FindWindow(L"TForm1", L"Form1");
   if(hWnd)
   {
    WaitForSingleObject(hMutex, INFINITE);
    ShowMessage("Program jest już uruchomiony");
    Application->Terminate();
   }
 }
        try
        {
                Application->Initialize();
                Application->MainFormOnTaskBar = true;
                Application->CreateForm(__classid(TForm1), &Form1);
                Application->Run();
        }
        catch (Exception &exception)
        {
                Application->ShowException(&exception);
        }
        catch (...)
        {
                try
                {
                        throw Exception("");
                }
                catch (Exception &exception)
                {
                        Application->ShowException(&exception);
                }
        }
        return 0;
}


Restart aplikacji
KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 String nazwa = ExtractFileName(Application->ExeName);

 Form1->Caption = "restart";

 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, nazwa.c_str());
 if(hEvent)
 {
  ShellExecute(NULL, L"open", nazwa.c_str(), NULL, NULL, SW_SHOW);

  static signal_event_at_end tmp(hEvent);
  Close();
 }
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Restart

Nowy postprzez polymorphism » środa, 15 grudnia 2010, 23:25

Przecież tu podałem jak to zrobić -> link.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia stronaNastępna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 6 gości