Restart

dział ogólny

Restart

Nowy postprzez Pitek » sobota, 26 grudnia 2009, 23:28

Czy jest taka możliwość aby w akcji jakiegoś przycisku program się restartuje tzn. Zamyka się i otwiera ponownie lub nie wiem jego działanie jest wznawianie do takiego stanu jak zaraz po jego uruchomieniu ?
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » sobota, 26 grudnia 2009, 23:37

Do restartu programu potrzebowałbyś drugiego programu, czyli program przed zamknięciem uruchamia drugi program, zamyka się, a ten drugi program go ponownie uruchamia i sam się zamyka. Masz tutaj duże pole manewru, możesz ten drugi program umieścić w zasobach programu ( ► patrz serwis: Cyfrowy Baron dział: porady -> różne -> Umieszczanie programu w programie, czyli coś w rodzaju instalatora). Przed zamknięciem program pierwszy wypakuje program drugi i go uruchomi, a potem jak pisałem...

Co do ustawiania programu do stanu początkowego, to nie nie bardzo wiem co przez to rozumiesz. Możesz przechowywać w pliku *.INI konfigurację domyślna programu i ładować ją kiedy potrzeba.
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Pitek » sobota, 26 grudnia 2009, 23:49

Dziękuję chyba o to mi chodzi.
A jak zapisać domyślne ustawienia programu w .INI ?
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
    NieznanyNieznana

Re: Restart

Nowy postprzez polymorphism » niedziela, 27 grudnia 2009, 12:13

Cyfrowy Baron napisał(a):Do restartu programu potrzebowałbyś drugiego programu [...]

Niekoniecznie. Można to zrobić przy użyciu muteksów lub eventów, w podobny sposób jak przy zabezpieczaniu aplikacji przed uruchomieniem w wielu instancjach.

To dajesz gdzieś na początku WinMain:
Kod: Zaznacz cały
HANDLE  hEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,"twoja_aplikacja.exe_restart");
if(hEvent)
{
   DWORD res = WaitForSingleObject(hEvent,INFINITE);
   if(res != WAIT_OBJECT_0)
   {
      /* coś poszło nie tak, zamykasz aplikację */
      return -1;
   }

   CloseHandle(hEvent);
}


Kod restartujący:
Kod: Zaznacz cały
/* klasa pomocnicza  */
class signal_event_at_end
{
   HANDLE m_event;
public:
   signal_event_at_end(HANDLE event)
      :m_event(event) {}
   ~signal_event_at_end()
   {
      if(!m_event)return;
      SetEvent(m_event);
      CloseHandle(m_event);
   }
};

...

hEvent = CreateEvent(NULL,FALSE,FALSE,"twoja_aplikacja.exe_restart");
if(hEvent)
{
   ShellExecute(NULL,"open","twoja_aplikacja.exe",NULL,NULL,SW_SHOW);
   static signal_event_at_end tmp(hEvent);
   
   /* zamykasz aplikację */
}
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 13:35

Bardzo sprytnie! Nie bardzo jednak rozumiem czemu ma służyć ta klasa pomocnicza, bez niej kod również działa prawidłowo.



Pozwolę sobie przedstawić podobne rozwiązanie oparte na mutexach:

W pliku projektu np. Projekt1.cpp (menu: Project ->View source) tworzysz mutex i podpinasz go pod funkcję WaitForSingleObject:

Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "nazwa_aplikacji.exe_restart"); /* nazwa jest dowolna, tutaj: "nazwa_aplikacji.exe_restart" */

  if(!hMutex) hMutex = CreateMutex(0, 0, "nazwa_aplikacji.exe_restart"); /* nazwa taka sama jak wyżej więc tutaj: "nazwa_aplikacji.exe_restart" */
  else
  {
   if(WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0)
   {
    return -1;
   }
  }
    try
    {

         Application->Initialize();
         SetApplicationMainFormOnTaskBar(Application, 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;
}
//---------------------------------------------------------------------------


W pliku źródłowym głównego formularza aplikacji tworzysz kod restartujący aplikację, np. w zdarzeniu OnClick dla przycisku Button1:

Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShellExecute(NULL,"open","nazwa_aplikacji.exe",NULL,NULL,SW_SHOW); /* nazwa_aplikacji.exe to nazwa pliku programu */
Close();   
}
//---------------------------------------------------------------------------


Dodatkowo można dodać kod zabezpieczający aplikację przed uruchomieniem kopii programu w zdarzeniu OnCreate formularza głównego:

Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
THandle h = (int)CreateSemaphore(NULL, 0, 1, "nazwa_aplikacji.exe.semaphore"); /* nazwa jest dowolna, tutaj: "nazwa_aplikacji.exe_semaphore" */
if((h != 0) && (GetLastError() == ERROR_ALREADY_EXISTS))
{
  CloseHandle((void *)h);
  ShowMessage("Ten program jest już uruchomiony!");
  Application->Terminate();
}
}
//---------------------------------------------------------------------------
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
    NieznanyNieznana

Re: Restart

Nowy postprzez polymorphism » niedziela, 27 grudnia 2009, 14:14

Nie bardzo jednak rozumiem czemu ma służyć ta klasa pomocnicza, bez niej kod również działa prawidłowo.

U mnie nie działa prawidłowo, aplikacja zawiesza się - WaitForSingleObject bez końca czeka aż event przejdzie w stan signaled. A że zamknięcie procesu, który stworzył event'a nie powoduje przełączenie go w stan signaled, trzeba to zrobić jawnie, poprzez destruktor klasy pomocniczej. Obiekt tej klasy definiuję jako statyczny po to, żeby stan event'a zmienić dopiero po wyjściu z WinMain, chwilę przed zamknięciem procesu.

Pozwolę sobie przedstawić podobne rozwiązanie oparte na mutexach:

Ale na tym rozwiązaniu nie otworzysz dwóch instancji aplikacji...
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 14:52

Ale na tym rozwiązaniu nie otworzysz dwóch instancji aplikacji...

Nie wiem czy dobrze zrozumiałem. Twierdzisz, że nie uruchomię dwóch kopii tego samego programu?!

Utworzę jeżeli usunę kod ze zdarzenie OnCreate. Mutex nie blokuje tutaj możliwości uruchomienia kopii programu, więc bez kodu ze zdarzenie OnCreate można uruchomić dowolną liczbę kopii. Problemem byłoby dopiero restartowanie każdej kopii.
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Pitek » niedziela, 27 grudnia 2009, 15:38

Pewnie znowu zapomniałem dodać bardzo ważnego szczegółu mianowicie program posiada blokade uruchomienia kilku kopii naraz :(
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 15:40

Mój kod zawiera blokadę uruchomienia kopii programu. Jeżeli swoją blokadę oparłeś na muteksach, to usuń to i zrób to tak jak podałem, lub zrób jak podał polymorphism i dodaj mój kod dla zdarzenie OnCreate, chyba że polymorphism uzupełni swój kod.
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
    NieznanyNieznana

Re: Restart

Nowy postprzez polymorphism » niedziela, 27 grudnia 2009, 16:05

Nie wiem czy dobrze zrozumiałem. Twierdzisz, że nie uruchomię dwóch kopii tego samego programu?!

Pomyliłem się, dwie uruchomisz, ale większej ilości już nie. Żeby nie było, mowa o tym kodzie:
Kod: Zaznacz cały
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
   HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "nazwa_aplikacji.exe_restart");
   if(!hMutex) hMutex = CreateMutex(0, 0, "nazwa_aplikacji.exe_restart");
   else
   {
      if(WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0)
      {
         return -1;
      }
   }

   ...
   
    return 0;
}

Wprawdzie nie sprawdzałem go, ale na oko wygląda, że hMutex będzie istniał przez cały czas pracy aplikacji, więc następne uruchomienie aplikacji spowoduje, że OpenMutex zwróci uchwyt i przejdzie w stan oczekiwania. Tylko, po głębszym przeanalizowaniu tego kodu, stwierdzam, że ten kod w ogóle nie będzie działał tak jak trzeba. Aplikacja tworzy muteksa, ale nie przejmuje własności (bInitialOwner == FALSE), przez co w następnym uruchomieniu nie będzie czekać na zamknięcie aplikacji, tylko przejmie własność wywołując WaitForSingleObject. Ustawiając bInitialOwner na TRUE także nie załatwi sprawy, bo WaitForSingleObject zwróci WAIT_ABANDONED, co w konsekwencji zakończy aplikację (-1).
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Pitek » niedziela, 27 grudnia 2009, 16:15

W zdarzeniu OnClose Form1 mam takie coś :
Kod: Zaznacz cały
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(modify == true)
{
  int mbResult2 = MessageBox(NULL,
              "Dokonano zmian. Czy chcesz zapisać swoją pracę?",
              "Zakończ", MB_YESNOCANCEL | MB_ICONQUESTION);
  if(mbResult2 == IDNO)
  {
   Action = caFree; // odblokowuje zamykanie jeżeli zablokowane
   return;
  }
  if(mbResult2 == IDCANCEL)
  {
   Action = caNone; // blokuje zamknięcie formularza
   return;
  }
  if(mbResult2 == IDYES)
  {
   MessageBox(NULL,"Aby zapisać dotychczasowy efekt pracy użyj funkcji Zapisz w lewym dolnym rogu okna programu.",
              "Zakończ", MB_OK | MB_ICONINFORMATION);
   LabeledEdit1->Color=clYellow;
   Action = caNone;
   return;
  }
}
else Action = caFree;
}

I to kłuci mi się z tą funkcją restartu w momencie kiedy dokonano zmian i klikne nie to nie restartuje mi się program a czasem pisze że blokada program jest już uruchomieny.
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
    NieznanyNieznana

Re: Restart

Nowy postprzez polymorphism » niedziela, 27 grudnia 2009, 16:19

Pewnie znowu zapomniałem dodać bardzo ważnego szczegółu mianowicie program posiada blokade uruchomienia kilku kopii naraz

To z moim kodem powinno śmigać:
KOD cpp:     UKRYJ  
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        /* tu kod z eventem */

        HANDLE hSem = CreateSemaphore(NULL, 0, 1, "nazwa_aplikacji.exe.semaphore");
        if(hSem && GetLastError() == ERROR_ALREADY_EXISTS)
        {
                CloseHandle(hSem);
                ShowMessage("Ten program jest już uruchomiony!");
                return 0;
        }


        ...
       
       
        CloseHandle(hSem);
        return 0;
}
Ostatnio edytowano środa, 15 grudnia 2010, 23:25 przez polymorphism, łącznie edytowano 2 razy
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 16:28

Pomyliłem się, dwie uruchomisz, ale większej ilości już nie.


Rzeczywiście, to prawda. Co do reszty to nie do końca masz rację. Program można restartować w nieskończoność.
Masz jednak rację, że kod nie działa do końca prawidłowo, czyli działa niezgodnie z założeniami, dlatego poprawiam:

Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "twoja_aplikacja.exe_restart");

  if(!hMutex) hMutex = CreateMutex(0, 0, "twoja_aplikacja.exe_restart");
  else
  {
   HWND hWnd = FindWindow("TForm1", NULL); /* nazwa klasy formularz głównego powinna być unikatowa, tutaj TForm1 */
   if(hWnd)
   {
    WaitForSingleObject(hMutex, INFINITE);
    ShowMessage("Program jest już uruchomiony");
    Application->Terminate();
   }
  }
    try
    {

         Application->Initialize();
         SetApplicationMainFormOnTaskBar(Application, 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;
}
//---------------------------------------------------------------------------


Teraz kod ze zdarzenia OnCreate jest zbędny, wręcz niepotrzebny (wcześniejsze posty), ale muteks nie zezwala na uruchomienie kopii programu, gdyż w przypadku restartu powodowałoby to błędy z tym, która kopia ma być restartowana.
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
    NieznanyNieznana

Re: Restart

Nowy postprzez polymorphism » niedziela, 27 grudnia 2009, 17:09

Taka pobieżna analiza:

  1. CreateMutex, bez przejęcia własności.
  2. OpenMutex, FindWindow zwróci uchwyt, wszak jeśli muteks istnieje, to na 90% okno też. Przejęcie własności funkcją WaitForSingleObject. Ta część jest zupełnie bez sensu - przejmujesz własność, żeby ją zaraz oddać, wychodząc z aplikacji.

Może się gdzieś rypnąłem, ale nie wydaje mi się...
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
    NieznanyNieznana

Re: Restart

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 17:21

FindWindow, jest zbędne, a WaitForSingleObject czeka tylko na zamknięcie aplikacji by móc uruchomić kopię, czyli pierwsza aplikacja zostaje zamknięta, i jednocześnie zostaje wydane polecenie ponownego uruchomienia, czyli w zasadzie jest to polecenie uruchomienia kopii, która czeka, aż pierwsza aplikacja zostanie zamknięta, gdy to się stanie, kopia się uruchamia. Reszta zapobiega uruchomieniu kopii programu. Zapomniałem jednak o funkcji ReleaseMutex(hMutex)

Wersja ostateczna:
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
      HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "twoja_aplikacja.exe_restart");

      if(!hMutex) hMutex = CreateMutex(0, 0, "twoja_aplikacja.exe_restart");
      else
      {
       WaitForSingleObject(hMutex, INFINITE);
       ShowMessage("Program jest już uruchomiony");
       Application->Terminate();
      }

         Application->Initialize();
         SetApplicationMainFormOnTaskBar(Application, true);
         Application->CreateForm(__classid(TForm1), &Form1);
         Application->Run();
         
     ReleaseMutex(hMutex);
    }
    catch (Exception &exception)
    {
         Application->ShowException(&exception);
    }
    catch (...)
    {
         try
         {
             throw Exception("");
         }
         catch (Exception &exception)
         {
             Application->ShowException(&exception);
         }
    }
    return 0;
}
//---------------------------------------------------------------------------


działa prawidłowo, bez niespodzianek, co można sobie obejrzeć:


restart.zip





Z moich analiz wynika, że to nie powinno działać, ale działa i nie bardzo rozumiem dlaczego!?

Program jest uruchamiany po raz pierwszy.
Tworzony jest mutex.
Program jest restartowany.
Z poziomu pierwszego programu uruchamiana jest jego kopia.
Kopia sprawdza - mutex istnieje.
Wywoływana jest funkcja WaitForSingleObject(hMutex, INFINITE), która czeka aż pierwszy program zakończy działanie.
Pierwszy program kończy działanie, okres oczekiwania dobiega końca.
Teraz powinien zostać wywołany kod:

Kod: Zaznacz cały
ShowMessage("Program jest już uruchomiony");
Application->Terminate();


Tak się jednak nie dzieje. Po zakończeniu oczekiwania program wychodzi z warunku i pomijając podany kod, przechodzi do dalszych instrukcji.
Dlaczego???

A teraz inaczej:

Program jest uruchamiany po raz pierwszy.
Tworzony jest mutex.
Uruchamiam kopię programu - nie restartuję, lecz uruchamiam drugi plik ręcznie.
Kopia sprawdza - mutex istnieje.
Wywoływana jest funkcja WaitForSingleObject(hMutex, INFINITE), która czeka aż pierwszy program zakończy działanie.
Kopia powinna czekać na zakończenie pierwszego programu i dopiero potem przejść do dalszych instrukcji, tak się jednak nie dzieje. Kopia pomija funkcję: WaitForSingleObject(hMutex, INFINITE) i przechodzi do dalszych instrukcji kończąc działanie programu.
Dlaczego???



Po zastanowieniu, chyba wiem.

Przypadek 1:
Funkcja WaitForSingleObject odnosi się do procesów potomnych, gdy restartuję program, jego kopia jest procesem potomnym, dlatego funkcja działa WaitForSingleObject prawidłowo, oczekując na na zakończenie działania pierwszego programu. To nie tłumaczy jednak dlaczego dalsze instrukcje w warunku nie są wykonywane.

Przypadek 2:
Jeżeli kopia programu zostanie uruchomiona ręcznie, wtedy funkcja WaitForSingleObject w tej kopii nie ma zastosowania, gdyż nie jest procesem potomnym, funkcja od razu kończy działanie i wykonywane są dalsze instrukcje.

Nie rozumiem jednak dlaczego w pierwszym przypadku pomijane są instrukcje:

Kod: Zaznacz cały
ShowMessage("Program jest już uruchomiony");
Application->Terminate();


Kod działa prawidłowo. Niejasne jest dla mnie tylko pomijanie tych instrukcji. Dlaczego funkcja WaitForSingleObject po zakończeniu oczekiwania od razu wychodzi z warunku i pomija część instrukcji.
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
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
    NieznanyNieznana

Nastę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