1

Konu: Çalışan programları bulmak

Foxpro 8.0'da hazırladığım bir program var: "program.exe". Foxproda yazacağım bir programla "program.exe"nin açık olup olmadığını (yani çalışıyor olup olmadığını) kontrol edip eğer çalışıyorsa kapatmak istiyorum. Yardımcı olabilirseniz sevinirim...

2

Re: Çalışan programları bulmak

Visual Fox Pro
lcExeName = 'program.EXE'

 
GetProcessesActive()
 
SELECT * FROM ProcList WHERE UPPER(szexefile) == UPPER(m.lcExeName) TO SCREEN noconsole
IF ( _Tally > 0)
    IF MESSAGEBOX( m.lcExeName + " calisiyor, gercekten katledeyim mi?",4+32+256) = 6
       KillExe(m.lcExeName)       
    endif
endif
 
 
PROCEDURE KillExe(tcModuleName)
  SELECT ProcessID FROM ProcList ;
    WHERE UPPER(szexefile) == UPPER(m.tcModuleName) ;
    INTO ARRAY aProcessID
 
  IF (_Tally > 0)
    declare integer OpenProcess in Win32API ;
      integer dwDesiredAccess, integer bInheritHandle, integer dwProcessID
    declare integer TerminateProcess in Win32API ;
      integer hProcess, integer uExitCode
    return TerminateProcess(OpenProcess(1, 1, aProcessID), 0) > 0
  ENDIF
ENDPROC
 
 
Procedure GetProcessesActive
  #Define TH32CS_SNAPPROCESS  2
  #Define TH32CS_SNAPTHREAD   4
  #Define TH32CS_SNAPMODULE   8
  #Define MAX_PATH          260
  #Define PE32_SIZE  296
 
  Declare Integer CloseHandle In kernel32 Integer hObject
  Declare Integer CreateToolhelp32Snapshot In kernel32;
    INTEGER dwFlags, Integer th32ProcessID
  Declare Integer Process32First In kernel32;
    INTEGER hSnapshot, String @ lppe
  Declare Integer Process32Next In kernel32;
    INTEGER hSnapshot, String @ lppe
  Declare RtlMoveMemory In WIN32API ;
    INTEGER @DestNumeric, ;
    STRING @pVoidSource, ;
    INTEGER nLength
 
  Create Cursor ProcList ;
    (ProcessID i,;
    cntThreads i,;
    ParentPID i,;
    szexefile m)
 
  Local hSnapshot, lcBuffer, lSuccess
 
  hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0)
  lcBuffer = Int2Str(PE32_SIZE) + Replicate(Chr(0), PE32_SIZE-4)
 
  lSuccess = ( Process32First(hSnapshot, @lcBuffer) # 0 )
  Do While m.lSuccess
    PROCESSENTRY32_ToCursor(m.lcBuffer)
    lSuccess = ( Process32Next(hSnapshot, @lcBuffer) # 0 )
  Enddo
  CloseHandle(hSnapshot)
 
Function PROCESSENTRY32_ToCursor
  Lparameters tcBuffer
  Local szexefile
  m.szexefile = Substr(m.tcBuffer,37)
  m.szexefile = Substr(m.szexefile, 1, ;
    AT(Chr(0),m.szexefile)-1)
  Insert Into ProcList ;
    (ProcessID,    cntThreads, ParentPID, szexefile) ;
    values ;
    (Substr2Num(m.tcBuffer,9,4), ;
    Substr2Num(m.tcBuffer,21,4), ;
    Substr2Num(m.tcBuffer,25,4), ;
    m.szexefile    )
Endfunc
 
Function Substr2Num
  Lparameters tcStr, tnStart, tnSize
  Return Str2Num(Substr(m.tcStr, m.tnStart, m.tnSize), m.tnSize)
Endfunc
 
Function Str2Num
  Lparameters tcStr,tnSize
  Local m.lnValue
  m.lnValue=0
  RtlMoveMemory(@lnValue, m.tcStr, m.tnSize)
  Return m.lnValue
Endfunc
 
Function Int2Str
  Lparameters tnValue, tnSize
  Local ix, lcReturn
  m.tnSize = Iif(Empty(m.tnSize),4,m.tnSize)
  lcReturn = ''
  For ix=1 To m.tnSize
    m.lcReturn = m.lcReturn + ;
      Chr(Bitand(Bitrshift(m.tnValue, (m.ix-1)*8),0xFF))
  Endfor
  Return m.lcReturn
Endfunc

Uyari: Bu zor kullanarak kapatma yontemi (Task managerdan kapatmak gibi). Neden gerektigini yazmamissin, belki de tehlikeli bir silah verdim eline.

3

Re: Çalışan programları bulmak

Öncelikle çok teşekkür ederim cevabınız için. Aslında amacım client'larda bulunan program.exe'yi server'daki exe ile karşılaştırıp farklıysa update etmek. Bunu yaparken de program.exe'nin çalışmadığını garanti etmem lazım. Ama sizin uyarınızı dikkate alarak çalışan programı "katletmek" smile yerine kullanıcıya programın çalıştığına ve kapatılması gerektiğine dair bir uyarı verip update'i yapmayacağım.

Bu arada debugger'da da bir sorun oluştu, belki bu konuda da yardımcı olabilirsiniz. Daha önce çalışan programları bulabilmek için DDEInitiate kullanmaya çalışmıştım ama olmadı (eğer bağlantı kurulursa -1 dışında bir değer dönecek ve program açık anlamına gelecekti). "program.exe"de çalışmayınca debugger'ın watch özelliğini kullanarak çalışan bazı programlarda bu komutu denedim (örn. word, excel, svchost, services, outlook.exe vs.). Debugger'ı kapatırken bunları silmedim sanırım. Şimdi debugger'ı açmam gerektiğinde "Remote data not accessible. Start application 'OUTLOOK.EXE'?" (ve diğer programlar için de ayrı ayrı veriyor bu uyarıyı) uyarısını veriyor. No dersem sonsuz bir döngüye giriyoruz, sürekli soruyor. Yes dersem bazılarını çalıştırıyor, bazılarını çalıştıramıyor ve tekrardan hepsi için bu messagebox geliyor. Yani debugger'ı artık kullanamıyorum! Bilmiyorum sorunun kaynağı benim önceki denemelerim mi ama bana en mantıklı açıklama bu geldi.

Yolladığınız kod için tekrar teşekkür ederim.

4 Son düzenleyen, cetinbasoz (21.08.2008 23:14:35)

Re: Çalışan programları bulmak

Ah bastan soyleseydin:) Daha bugün yeni bir "LiveUpdate" yazdım:) Benim yaptıgım soyle:

-Bir FTP programı belli bir yerde yenis var mı diye bakıyor ve varsa inidiriyor (bugunkünde bu parcayı asıl programdan bagımsız calısan bir exe yaptım).
-Ilk olarak calısan program aslında bir "yukleyici". Belli bir dizini kontrol ediyor download edilmiş yeni bir versiyon var mı diye. Varsa eskisini yedekleyip yenisini kopyeliyor ve onu calıştırıp kendisini sonlandırıyor.

Debugger sorununu cozmek:

Visual Fox Pro
use sys(2005) again

BROWSE FOR id = "WATCHEXPR"
*Data'yı ac ve temizle
use

5

Re: Çalışan programları bulmak

Debugger sorunu da halloldu. Yardımlarınız için tekrar teşekkür ederim.

6

Re: Çalışan programları bulmak

aseray  Aslında amacım client'larda bulunan program.exe'yi server'daki exe ile karşılaştırıp farklıysa update etmek demişsin.Neden her cliente ayrı ayrı exe yüklemek yerine,exe yide server üzerinden çalıştırmıyorsun.Tek yapman geren clientler e masa üssünden ağdaki exe dosyasına kısayol tanımlamak.Daha pratik olmaz mı?

En büyük sermaye nakit,nakit sermaye vakittir...

7

Re: Çalışan programları bulmak

dolayısıyla her clientdeki exe yide güncellenek gibi,bir problemde kalmamış olur :-)

En büyük sermaye nakit,nakit sermaye vakittir...

8

Re: Çalışan programları bulmak

Sayın neyzen,

Daha önce forumda, sizin önerdiğiniz yöntemin yavaşlamaya yol açtığı yönünde bir tartışma olmuştu. Ben de sistemi böyle kurdum. Yaptığım testlerde bu yöntemin hızlı bir şekilde çalıştığını gördüm. Yine de dediğiniz yöntem aklımda, ilerde gerekebilir, teşekkürler...

9

Re: Çalışan programları bulmak

Single Point Of Failure diye bir kavram okumuştum sanırım bir yerlerde. Aklımda böyle bir şeyler kalmış en azından. Hangi standarttadır nerededir şimdi hatırlamıyorum ama benim kendi adıma geliştirdiğim projelerde kesinlikle bu yöntemi tercih ediyorum. VFP nin genel data trafiğinin yarattığı yük düşünüldüğünde 5-10 bilemedin abart 20-30 mb lik trafiklerin çok ta önemli olmadığını düşünüyorum.

Ayrıca da ben gene kendi uygulamalarımda VRC ( Version Release Control ) uyguladığım için zaten uygulama esnasında birden fazla versionun çalışması söz konusu olabiliyor. ( Örneğin sistem yöneticileri ve aklı başında kullanıcılara yeni versionu açıp, sıradan kullanıcıların halihazırdaki version ile çalışması ve makul bir süre sonunda problem yoksa yeni versionun release edilmesi gibi ) Böyle olunca da benim için server üzerindeki exe ye herkesin erişmesi benim de tercih ettiğim bir yöntem.

Ama biliyorum ki ftp den kendi kendini update eden exelerin her clienta ayrı ayrı yüklenmesi yöntemini kullanan arkadaşlar da var. Ve ben pratik olarak ta biliyorum ki bu da son derece sorunsuz olarak kullanılabiliyor. Bir yerden sonra sanki neredeyse teknik bir seçim değil de kişisel tercih halini alabilen bir konu gibi geliyor bu bana.

10

Re: Çalışan programları bulmak

Çetin Bey, daha önce bir liveupdate programı yazdığınızı, yükleyici programını ana programdan ayrı bir exe yaptığınızı, bu programın ana program için güncel versiyon olup olmadığını kontrol ederek varsa eskisinin yedeğini alıp yenisini kopyaladığını ve kendisini kapatarak ana programı çalıştırdığınızı söylemiştiniz. Benim kurduğum sistem de hemen hemen aynı mantıkla çalışıyor. Yalnız bir sorun var. Programın bir şekilde mutlaka "yükleyici" kullanılarak çalıştırılması lazım. Yani anaprogram.exe'den çalıştırılmamalı. Bunun kontrolünü nasıl yapabiliriz? yükleyici.exe'den anaprogram.exe'ye parametre geçmek gibi bir şey olabilir mi? anaprogram bu parametreye bakarak yükleyici.exe'den mi gelindiğini yoksa doğrudan anaprogram.exe'nin mi çalıştırıldığını anlasın. Ya da başka bir yöntem?

11

Re: Çalışan programları bulmak

anaprogram.exe'nin dogrudan calistirilmasinda aslinda sorun yok. Kullanici bilerek ve isteyerek versiyon kontrolu olmadan mevcut versiyonu calistirmis oluyor. Yine de kontrol etmek istersen cozumu basit. anaprogram.exe bir parametre verildiginde calisabilir:

Visual Fox Pro
* anaprogram.exe icin main.prg

lparameters kimCagirdi
if m.kimCagirdi <> 'ASeray'
   return
endif
* ...

Yukleyici.exe kodu:

Visual Fox Pro
* ...

declare long ShellExecute in "shell32.dll" ;
    long hwnd, string lpszOp, ;
    string lpszFile, string lpszParams, ;
    string lpszDir, long nShowCmd
 
ShellExecute(0,'Open', 'anaprogram.exe', 'ASeray', 0,1)

12 Son düzenleyen, sasmazali (24.12.2010 12:39:53)

Re: Çalışan programları bulmak

Çetin hocam sunucuda bir exeyi birden fazla veya bizim belirttiğimiz sayıdan fazla çalışmasını istemiyoruz yukarıda verdiğiniz kodda exeyi yakalıyor fakat kullanıcısını nasıl tespit edebiliriz ? aksi takdirde tüm kullanıcılardan geldiği için tespit edemiyorum
daha doğrusu kullanıcın ID sini bulmak gerekiyor şimdide normalde ben SYS(0) ile kullanıcı adını yakalıyordum ama id sini hiç aramayı düşünmedim

13

Re: Çalışan programları bulmak

sizin kodlar sanırım farklı. ben bunları nerden buldum hatırlamıyorum ama işime yarıyor:

Visual Fox Pro
DECLARE INTEGER CreateEvent IN WIN32API ;

   INTEGER lpEventAttributes, ;
   SHORT bManualReset, ;
   SHORT bInitialState, ;
   STRING @ lpName
DECLARE INTEGER GetLastError IN Win32API
DECLARE CloseHandle IN Win32API INTEGER hObject
nEh = CreateEvent(0,0,1, PROGRAM(0) + '.EVENT')
IF GetLastError() = 183 OR nEh = 0
   *  There's an instance running already (183) or the Event can't be defined
   *  So don't do it;  do release the handle, since it's harmless and should
   *  be done rather than relying on Windows to clean up after itself
   =CloseHandle(nEh)
   MessageBox("Bu programın bir kopyası daha açık!.."+Chr(13)+;
       "Aynı anda iki kopya çalışamaz!..",0+16+4096,"Hata")
   QUIT
ENDIF
Haksızlıklar karşısında susanlar, dilsiz şeytanlardır!
www.metinemre.com

14

Re: Çalışan programları bulmak

Metin hocam çetin abinin verdiği kodda tüm çalışanlar listeleniyor sadece kullanıcı id sini bulabilsem geri kalanı çözeceğim SYS(0) işimi çözmüyor siznkinide test ettim fakat birincisi daha çok işime yarayacak daha detaylı

15

Re: Çalışan programları bulmak

Artik WMI'in bulunmadigi makine bulmak zor. O nedenle WMI kullanmak daha kolay geliyor. Bu MS MSDN yardim WMI Win32_Process class aciklamalarindaki ornegin biraz modifiye hali:


Visual Fox Pro
Local objWMIService,User,Domain

objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
 
colProcesses = objWMIService.ExecQuery( "select * from win32_process where Name='VFP9.exe'" )
For Each objProcess In colProcesses
    Store '' To User,Domain
    Try
        If objProcess.GetOwner ( @User, @Domain ) = 0
            ? "Process ", objProcess.Caption, " belongs to ", m.Domain, m.USer
        Else
            ? "Problem  getting the owner for process", objProcess.Caption
        Endif
    Catch
    Endtry
Next

16

Re: Çalışan programları bulmak

Süprizlerle dolusun Çetin abi. inan bugün 4 de kadar senin verdiğin kodla ulaşılan bilgilere ulaşmak için uğraştım. Teşkkür. Paylaşım yapan herkese

17 Son düzenleyen, konuka (16.01.2011 08:26:53)

Re: Çalışan programları bulmak

yukarıdaki kodlar ile çalışan program isimlerini bulabiliyoruz,
aradığım o programın çalıştırdığı "handle" veya "window name"
EnumThreadWindows 'un VFP uygulamasını beceremedim.
*---
yapmak istediğim:

Visual Fox Pro
DECLARE INTEGER SetParent IN user32;

        INTEGER hWndChild, INTEGER hWndNewParent
SetParent(hCalc, _screen.HWND)

ile örneğin calc.exe'yi VFP formu içinde çalıştıracağım. hcalcı bulamıyorum.

Findwindow ile "Hesap Makinesi" diye arayıp bulabilirim, ancak üniversal olmaz, ingilizce makinelerde "calculator" demem gerekiyor etc ...
belki de türkçe ingilizce çözüm aşağıdakigibi:

Visual Fox Pro
hCalc = MAX( FindWindow(null, "Calculator"), FindWindow(null, "Hesap Makinesi"))

IF hcalc>0
SetParent(hCalc, _screen.HWND)
endif
VFP9 SP2

18

Re: Çalışan programları bulmak

Visual Fox Pro
DECLARE integer FindWindow in WIN32API string cNull, string cWinName

 
hWnd = FindWindow('CalcFrame', 0)
? m.hwnd

19

Re: Çalışan programları bulmak

Çetin, aklıma gelen herşeyi denemiştim - gene çalışmadı.
wincalc ı ilk çağırdığımda handle i veriyor - sonra aradığımda bulamıyorum !

VFP9 SP2