Program aynı anda sadece bir tane çalışsın - Mutex

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Kullanıcı avatarı
mege
Admin
Mesajlar: 2360
Kayıt: 05 Şub 2004 04:32
Konum: Beşiktaş
İletişim:

Program aynı anda sadece bir tane çalışsın - Mutex

Mesaj gönderen mege »

eğer bir programın aynı anda sadece bir tane çalışmasını istiyorsanız :
proje dosyasında (project1.dpr)
beginden sonra

Kod: Tümünü seç

  if (HPrevInst <> 0) then
     Exit;
HPrevInst değişkeni sadece Delphi 1 de çalışıyor. delphi 5 ve üstü için mutex fonksiyonu tanımlayıp ondan karşılaştırma yapmanız lazım.

Kod: Tümünü seç

program Project1;

uses
  Forms,
  windows,  // Mutex fomksiyonu için
  sysutils, // Uppercase ve ExtractFileName fonksiyonları için
  dialogs,  // Showmessage için sadece
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

 var hMyMutex : tHandle;
begin
  hMyMutex := CreateMutex (nil, True,pChar (Uppercase (ExtractFileName (Application.ExeName))));
  if (hMyMutex = 0) or (GetLastError = error_Already_Exists) then
    begin
    showmessage('aynı anda iki program çalıştıramazsınız');
    Application.Terminate;
    end;
  try
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
    finally
    ReleaseMutex (hMyMutex);
  end;
end.
Kaynak
tabi exe adını değiştirip onu çalıştırıldığı zaman buda yemiyor.
:idea: aklıma gelen registerda bir bit tanımlayıp onu kontrol etmek. veya findwindow ile başlığıda arattırmak. ikinci yoldan gittim.

Kod: Tümünü seç

program Project1;

uses
  Forms,
  windows,  // Mutex fomksiyonu için
  sysutils, // Uppercase ve ExtractFileName fonksiyonları için
  dialogs,  // Showmessage için sadece
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

 var hMyMutex : tHandle;
begin
  hMyMutex := CreateMutex (nil, True,pChar (Uppercase (ExtractFileName (Application.ExeName))));
  if (hMyMutex = 0) or (GetLastError = error_Already_Exists) then
    begin
    showmessage('aynı anda iki program çalıştıramazsınız');
    Application.Terminate;
    end;

  // Form1.Caption tasarım anında boş olmalı. Form Createde eklenmeli
  if FindWindow(Nil, 'Deneme Form1') <> 0 then
  begin
    showmessage('Lütfen ikinci exeyi silin! aynı anda iki program çalıştıramazsınız');
    Application.Terminate;
  end;
  //Form1'in Create olayına
  //Form1.Caption:='Deneme Form1';

  try
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
    finally
    ReleaseMutex (hMyMutex);
  end;
end.
:?: değişil fikirleri olan varmı?
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7603
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Mesaj gönderen mussimsek »

Bir ara ben mutex ile aynı işlevi yapmıştım. Çok iyi çalışıyor. Tek dezavantajı var, eğer program normal sonlanıp, mutex silinmezse (mesela task manager'dan kapatırsanız vs.) windowsu kapatıp açmadan programı tekrar çalıştıramıyorsun.

Ama ben hemen hemen hiç sıkıntı yaşamamıştım bu konuda.

Kolay gelsin.
Kullanıcı avatarı
fahrettin
Admin
Mesajlar: 2619
Kayıt: 11 Haz 2003 10:38
Konum: İstanbul
İletişim:

Mesaj gönderen fahrettin »

Yıllardır project source'un en basına

Kod: Tümünü seç

var
  H: THandle;

begin
  H:=FindWindow(NIL,'Sarbak Üretim Takip (c) 2004');
  if (H<>0) then
  begin
    if IsIconic(H) then
      ShowWindow(H, SW_RESTORE);
    SetForegroundWindow(H);                          
    Halt(0);
  end;
  Application.Initialize;
  Application.Title := 'Sarbak Üretim Takip (c) 2004';
yazarak problemsiz kullanıyorum...
:)
* http://www.fahrettin.org Manzara Fotoğraflarım... :)
* http://delphiturkiye.gunduz.info Seminerler... ;)
* http://www.hakmar.com.tr Kalite bir haktır... 8)
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

ben basitce su sekilde kullanıyorum,project kodunun basına

Kod: Tümünü seç

  CreateMutex(nil, FALSE, 'PROGRAM_ICIN_BIR_ISIM');
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    Application.MessageBox(PChar('Program zaten çalışıyor'),
      PChar('PROGRAMIM'), MB_OK);
    Halt(0);
  end;
PROGRAM_ICIN_BIR_ISIM windowsa bu programın calıstıgının bildirilmesi gibi bir sey herhangi bir sey yazsam da sorun olmuyor bende
ÜŞENME,ERTELEME,VAZGEÇME
Kullanıcı avatarı
mege
Admin
Mesajlar: 2360
Kayıt: 05 Şub 2004 04:32
Konum: Beşiktaş
İletişim:

Mesaj gönderen mege »

gkimirti yazdı:ben basitce su sekilde kullanıyorum,project kodunun basına
arkadaşlar çok teşekkürler bende ilkönce gökmen hocamın deediği gibi yaptım ama exe kopyalanınca yemedi. ardından fahrettin abinin yaptığı gibi bi header arattırdım ikisi birleşince voltranı oluşturdu canavar gibi :) oldu :P
banada bi arkadaş sormuştu ama neyse. artık arasın bulsun :P
Kullanıcı avatarı
şimal
Kıdemli Üye
Mesajlar: 516
Kayıt: 10 Kas 2003 09:36
Konum: ANKARA

Mesaj gönderen şimal »

main formun create eventine bende bu kodu yazmıştım.
Şimdilik sorun çıkarmadı....



procedure Tfrmain.FormCreate(Sender: TObject);
var
Sem: THandle;
begin
Sem := CreateSemaphore(nil, 0, 1, 'PROGRAM_NAME');
if ((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle(Sem);
ShowMessage('Program Çalışmakda');
Halt;
end;
end;


"banada bi arkadaş sormuştu ama neyse. artık arasın bulsun"

mege sen bu makaleyi hazırlarken ben sorunu halletmiştim...
İmalı taşlamalardan hoşlanmıyorum.
bilmusa
Üye
Mesajlar: 18
Kayıt: 21 Nis 2004 11:31

teşekkür

Mesaj gönderen bilmusa »

TEŞEKKÜRLER ARKADAŞLAR SAGOLUN BAYA İLGİLENDİNİZ
Kullanıcı avatarı
supervisor
Üye
Mesajlar: 50
Kayıt: 07 Kas 2005 10:38
Konum: Turgutlu

Mesaj gönderen supervisor »

şimal yazdı:main formun create eventine bende bu kodu yazmıştım.
Şimdilik sorun çıkarmadı....



procedure Tfrmain.FormCreate(Sender: TObject);
var
Sem: THandle;
begin
Sem := CreateSemaphore(nil, 0, 1, 'PROGRAM_NAME');
if ((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle(Sem);
ShowMessage('Program Çalışmakda');
Halt;
end;
end;


"banada bi arkadaş sormuştu ama neyse. artık arasın bulsun"

mege sen bu makaleyi hazırlarken ben sorunu halletmiştim...
İmalı taşlamalardan hoşlanmıyorum.
Evt Kodlar Çalışıyor... Teşekkürler....
samety81
Üye
Mesajlar: 84
Kayıt: 07 Nis 2006 03:53

Mesaj gönderen samety81 »

merhabalar
ben fahrettin abinin dediği gibide yaptım
gkimirti abinin dediği gibide yaptım fakat ikinci kez actıgımda mesajı veriyor.ama programı baslatmayı sonlandırmıyor.
bu kodları on create denedim yanlıs denememiştirim umarım unit1 in on create sinde denedim
fakat windows hata raporu gonder gonderme hatası ile karsılasıyorum sürekli
Yardıma İhtiyacım var galiba TAM burda :)
Kullanıcı avatarı
aslangeri
Moderator
Mesajlar: 4322
Kayıt: 26 Ara 2003 04:19
Konum: Ankara
İletişim:

Mesaj gönderen aslangeri »

mege yazdı:proje dosyasında (project1.dpr)
beginden sonra
:wink:
Duyduğun Şeylerin Söylediklerim Olduğuna Eminim Ama
Anladığın Şeylerin Anlatmak İstediklerim Olduğuna Emin Değilim
samety81
Üye
Mesajlar: 84
Kayıt: 07 Nis 2006 03:53

Mesaj gönderen samety81 »

pardon ona tam dikkat etmemiştim
fakat :

Kod: Tümünü seç

program GEFinder;

uses
  Forms,Windows,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
var
  H: THandle;
begin
H:=FindWindow(NIL,'GEFinder');
  if (H<>0) then
  begin 
    if IsIconic(H) then
      ShowWindow(H, SW_RESTORE);
    SetForegroundWindow(H);
    Halt(0); 
  end;
  Application.Initialize;
  Application.Title := 'GEFinder';
Application.Run;
end.
şeklinde değiştirdim bu sefer hiç çalışmıyor proje sürekli kapanıyor :S
Yardıma İhtiyacım var galiba TAM burda :)
samety81
Üye
Mesajlar: 84
Kayıt: 07 Nis 2006 03:53

Mesaj gönderen samety81 »

şimal Tarih: 25 May 2004 01:16 Mesaj konusu:

--------------------------------------------------------------------------------

main formun create eventine bende bu kodu yazmıştım.
Şimdilik sorun çıkarmadı....



procedure Tfrmain.FormCreate(Sender: TObject);
var
Sem: THandle;
begin
Sem := CreateSemaphore(nil, 0, 1, 'PROGRAM_NAME');
if ((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle(Sem);
ShowMessage('Program Çalışmakda');
Halt;
end;
end;


"banada bi arkadaş sormuştu ama neyse. artık arasın bulsun"

mege sen bu makaleyi hazırlarken ben sorunu halletmiştim...
İmalı taşlamalardan hoşlanmıyorum.
bu kodla denedim oldu çok teşekkür ediyorum.
birde bir şey daha soracagım
peki bu çalışan projenin form1 ini burda calısıyorsa nasıl gösteririm.
yani eger proje acılmışsa yeni proje açma açık olan projeyi göster
Yardıma İhtiyacım var galiba TAM burda :)
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Project.dpr de yapmak daha uygun :wink:

Kod: Tümünü seç

program TekCalis;

uses
  Forms,
  windows, // Mutex fomksiyonu için
  sysutils, // Uppercase ve ExtractFileName fonksiyonları için
//  dialogs, // Showmessage için sadece
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}
const
  ProgramBasligi = 'Tek çalışan program';
var
  hMyMutex: THandle;
  Calisiyor: Boolean = False;
begin
  hMyMutex := CreateMutex(nil, True, pChar(Uppercase(ExtractFileName(Application.ExeName))));
  if (hMyMutex = 0) or (GetLastError = error_Already_Exists) then // 1.kontrol.
    Calisiyor := True;
  hMyMutex := FindWindow(nil, ProgramBasligi);
  if Calisiyor or (hMyMutex <> 0) then  // 2.kontrol.
  begin
    if IsIconic(hMyMutex) then
      ShowWindow(hMyMutex, SW_RESTORE);
    SetForegroundWindow(hMyMutex);
    Halt(0);
  end;
  //  ReleaseMutex(hMyMutex);
  Application.Initialize;
  Application.Title := ProgramBasligi;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
samety81
Üye
Mesajlar: 84
Kayıt: 07 Nis 2006 03:53

Mesaj gönderen samety81 »

ama abi ben bunları GEFinder.dpr ye koyunca programım hiç açılmıyor.
hep açılır açılmaz kapanıyor.
nasıl yaptın derseniz işte:

Kod: Tümünü seç

program GEFinder;

uses
  Forms,windows, // Mutex fomksiyonu için 
  sysutils, // Uppercase ve ExtractFileName fonksiyonları için 
dialogs, // Showmessage için sadece 

  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
 const 
  ProgramBasligi = 'GEFinder'; 
var 
  hMyMutex: THandle; 
  Calisiyor: Boolean = False; 

begin
  hMyMutex := CreateMutex(nil, True, pChar(Uppercase(ExtractFileName(Application.ExeName))));
  if (hMyMutex = 0) or (GetLastError = error_Already_Exists) then // 1.kontrol.
    Calisiyor := True; 
  hMyMutex := FindWindow(nil, ProgramBasligi); 
  if Calisiyor or (hMyMutex <> 0) then  // 2.kontrol. 
  begin 
    if IsIconic(hMyMutex) then
      ShowWindow(hMyMutex, SW_RESTORE);
    SetForegroundWindow(hMyMutex);
    Halt(0); 
  end;
//ReleaseMutex(hMyMutex); 

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.
bu şekilde .dpr yi düzenliyorum ama açılmıyor proje
Yardıma İhtiyacım var galiba TAM burda :)
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Bende bu haliyle çalışmakta :wink:
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Cevapla