Hallo zusammen,
ich erhalten von einem Kunden eine Anfrage, - kann geprüft werden, ob das Programm bereits gestartet ist und wenn das Programm aus der Taskleiste holen und wieder auf den Vordergrund bringen ?
Hat dies jemand schon gemacht ?
Programm bereits gestartet ?
Moderator: Moderatoren
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
- Herbert
- Der Entwickler von "Deep Thought"
- Beiträge: 1991
- Registriert: Do, 14. Aug 2008 0:22
- Wohnort: Gmunden am Traunsee, Österreich
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Programm bereits gestartet ?
Rolf
Ob es schon läuft:
So klappts auch in Windows 7
Das Hervorholen mach ich nicht, da das Ding ja in der Taskleiste steht.
Ob es schon läuft:
Code: Alles auswählen
#define MUTEX_ALL_ACCESS 2031617
PROCEDURE AppSys()
LOCAL cMutex:=Upper(AppName())+Chr(0)
LOCAL nH:=DllCall("KERNEL32.DLL", DLL_STDCALL,;
"OpenMutexA", MUTEX_ALL_ACCESS, 0, cMutex)
IF nH=0
nH:=DllCall("KERNEL32.DLL",DLL_STDCALL,"CreateMutexA",0,0,cMutex)
ELSE
MsgBox("Das Programm wird bereits ausgeführt!",cMutex)
QUIT
ENDIF
DllCall("KERNEL32.DLL",DLL_STDCALL,"ReleaseMutex",nH)
Das Hervorholen mach ich nicht, da das Ding ja in der Taskleiste steht.
Grüsse Herbert
Immer in Bewegung...
Immer in Bewegung...
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: Programm bereits gestartet ?
OK, etwas länger, aber das macht beides: Festellen ob das Programm schon läuft, und das laufende Programm nach vorne holen. Im Programm setze ich das so ein:
Und das eigentliche Programm:
Code: Alles auswählen
IF IsAppRunnung("Test.exe", NIL, .t.)
Return NIL
ENDIF
Code: Alles auswählen
#DEFINE SW_RESTORE 9
DLLFUNCTION ShowWindow(nWinHandle,nCmdShow) USING STDCALL FROM USER32.DLL
DLLFUNCTION BringWindowToTop(nWinHandle) USING STDCALL FROM USER32.DLL
DLLFUNCTION SetForegroundWindow(nWinHandle) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetWindow(nWinHandle,uCmd) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetWindowTextA(nWinHandle,@cWindowName,nMax) USING STDCALL FROM USER32.DLL
DLLFUNCTION IsWindowVisible(nWinHandle) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetWindowModuleFileNameA(nHandle,@cFileName,nSize) USING STDCALL FROM USER32.DLL
DLLFUNCTION IsIconic(nWinHandle) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetLastActivePopup(nWinHandle) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetWindowThreadProcessId(nForegroundHwnd,@nRetProcId) USING STDCALL FROM USER32.DLL
DLLFUNCTION GetForegroundWindow() USING STDCALL FROM USER32.DLL
*****************************************************************************************************************************
*** Läuft das Programm bereits?
*****************************************************************************************************************************
FUNCTION IsAppRunning(cExe,cTitle,lRestore)
/*
Developed on Windows 98 2nd Edition using XBase++ 1.7
Tested on Windows 98, 2000, and NT 4.0
Richard Pulliam
Richard@ClipperSolutions.com
*/
LOCAL nSearchColumn
LOCAL aRunningTasks
LOCAL i
LOCAL nWinHandleLast
LOCAL nWinHandleForeground
LOCAL nFindId
LOCAL nWinHandleFind
LOCAL nForeGroundId
LOCAL cColumnContents
LOCAL nPos
LOCAL nLenRunTasks
lRestore := IIf(lRestore == NIL, .T., lRestore) // default to restore running app
nSearchColumn := IIf(cExe#NIL, 2, 3) // what column to do search on, title or exe?
cExe := IIf(cExe == NIL, "", AllTrim(Upper(cExe)))
cTitle := IIf(cTitle == NIL, "", AllTrim(Upper(cTitle)))
aRunningTasks := GetRunningTasks() // returns a multidimensional array
// of row form {nHandle,ExeName,Title}
nLenRunTasks := Len(aRunningTasks)
IF WinNT() .AND. !EMPTY(cExe)
// this is because API function GetModuleBaseNameA does not return
// a full path and equivalent commands like GetModuleFileName
// did not work properly
cExe := IIf((nPos := RAt("\", cExe)) > 0, SubStr(cExe, nPos + 1), cExe)
ENDIF
FOR i := 1 TO nLenRunTasks
cColumnContents := AllTrim(Upper(aRunningTasks[i, nSearchColumn]))
IF cExe+cTitle == cColumnContents // running
IF .NOT. lRestore
RETURN(.T.)
ELSE
nWinHandleFind := aRunningTasks[i, 1]
nWinHandleForeground := GetForegroundWindow()
nForeGroundId := GetWindowThreadProcessId(nWinHandleForeground, 0)
nFindId := GetWindowThreadProcessId(nWinHandleFind, 0)
IF .NOT. (nForeGroundId == nFindId) .OR. .NOT. (IsIconic(nWinHandleFind) == 0)
nWinHandleLast := GetLastActivePopup(nWinHandleFind)
IF .NOT. (IsIconic(nWinHandleLast) == 0)
ShowWindow(nWinHandleLast, SW_RESTORE)
ENDIF
BringWindowToTop(nWinHandleLast)
SetForegroundWindow(nWinHandleLast)
ENDIF
RETURN(.T.)
ENDIF
ENDIF
NEXT
RETURN(.F.)
*****************************************************************************************************************************
*** Die laufenden Programme zusammensuchen
*****************************************************************************************************************************
STATIC FUNCTION GetRunningTasks()
LOCAL aSize := {0, 0}
LOCAL aPos := {0, 0}
LOCAL oDlg
LOCAL aList
oDlg := XbpDialog():new(AppDesktop(), , aPos, aSize, , .F.)
oDlg:clipSiblings := .T.
oDlg:drawingArea:ClipChildren := .T.
oDlg:create()
aList := GetTaskList(oDlg:gethWnd( )) // Get a list of all running programs
oDlg:destroy()
RETURN(aList)
*****************************************************************************************************************************
*** Die Taskliste zusammenstellen
*****************************************************************************************************************************
#DEFINE GW_HWNDNEXT 2
STATIC FUNCTION GetTaskList( nWinHandle )
LOCAL aList:={}
LOCAL cWindowName
LOCAL nVisible
LOCAL nSize := 256
LOCAL nBytes
LOCAL cFileName
LOCAL aProcesses
LOCAL nPos
LOCAL nId
IF WinNT()
aProcesses := GetNTProcesses()
ENDIF
WHILE(nWinHandle # 0)
cWindowName := Space(nSize)
nBytes := GetWindowTextA(nWinHandle, @cWindowName, nSize)
IF nBytes # 0
cWindowName := Left(cWindowName, nBytes)
nVisible := IsWindowVisible(nWinHandle)
IF nVisible == 1
IF .NOT. WinNT() // Win 95 or 98
cFileName := Space(nSize)
nBytes := GetWindowModuleFileNameA(nWinHandle, @cFileName, nSize)
AAdd(aList,{nWinHandle,Left(cFileName, nBytes - 1), cWindowName})
ELSE // executing in NT family
nId := 0
GetWindowThreadProcessId(nWinHandle,@nId)
IF (nPos := AScan(aProcesses, nId)) > 0
cFileName := aProcesses[nPos, 2]
AAdd(aList, {nWinHandle, cFileName, cWindowName})
ENDIF
ENDIF
ENDIF
ENDIF
nWinHandle := GetWindow(nWinHandle, GW_HWNDNEXT)
ENDDO
RETURN(aList)
*****************************************************************************************************************************
***
*****************************************************************************************************************************
#DEFINE PROCESS_ALL_ACCESS 2035711 // hex 1F0FFF
DLLFUNCTION OpenProcess(nDesiredAccess, lInheritHandle, nProcessId) ;
USING STDCALL FROM KERNEL32.DLL
DLLFUNCTION GetModuleBaseNameW(hProcess, hModule, @lpFileName, @nSize) ;
USING STDCALL FROM PSAPI.DLL
DLLFUNCTION CloseHandle(nProcessHandle) USING STDCALL FROM KERNEL32.DLL
*****************************************************************************************************************************
***
*****************************************************************************************************************************
STATIC FUNCTION GetNTProcesses()
LOCAL aProcessIds
LOCAL i
LOCAL nProcessHandle
LOCAL aRetVal := {}
LOCAL naHandleForProcess
LOCAL cFileName
LOCAL nSize := 0
LOCAL nBytes
LOCAL j
LOCAL nLenIds
LOCAL nLenHandles
aProcessIds := EnumerateProcesses()
nLenIds := Len(aProcessIds)
FOR i := 1 TO nLenIds
// get a handle to the process
nProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, 0, aProcessIds[i])
IF nProcessHandle > 0
// get an array of the module handles for the specified process
naHandleForProcess := EnumerateProcessModules(nProcessHandle)
IF (nLenHandles := Len(naHandleForProcess))>0
FOR j := 1 TO nLenHandles
cFileName := SPACE(256)
// GetModuleBaseName and GetModuleBaseNameA do not work here
// GetModuleFileName .and GetModuleFileNameA do not work here
nBytes := GetModuleBaseNameW(nProcessHandle, naHandleForProcess[j],;
@cFileName, @nSize)
IF nBytes > 0
cFileName := CleanUnicode(cFileName)
AAdd(aRetVal, {aProcessIds[i], cFileName})
ENDIF
NEXT
ENDIF
CloseHandle(nProcessHandle)
ENDIF
NEXT
RETURN(aRetVal)
*****************************************************************************************************************************
***
*****************************************************************************************************************************
STATIC FUNCTION CleanUnicode(cFileName)
cFileName := Upper(StrTran(cFileName, " ", ""))
cFileName := StrTran(cFileName, CHR(0), "")
RETURN(cFileName)
*****************************************************************************************************************************
***
*****************************************************************************************************************************
DLLFUNCTION EnumProcesses(@cProcesses,nSize,@nReturned) ;
USING STDCALL FROM PSAPI.DLL
*****************************************************************************************************************************
*** Klasse für eine Fortschrittsanzeige
*****************************************************************************************************************************
STATIC FUNCTION EnumerateProcesses()
LOCAL cProcesses:=SPACE(1024)
LOCAL nSize := 1024
LOCAL nReturned := 0
LOCAL nRetVal := 0
LOCAL nElements
LOCAL i
LOCAL nVal
LOCAL naProcessIds := {}
nRetVal:=EnumProcesses(@cProcesses,nSize,@nReturned)
IF nRetVal # 0
nElements := nReturned / 4
FOR i := 1 TO nElements
nVal := BIN2U(SubStr(cProcesses, 4 * (i - 1) + 1, 4))
AAdd(naProcessIds, nVal)
NEXT
ENDIF
RETURN(naProcessIds)
*****************************************************************************************************************************
***
*****************************************************************************************************************************
DLLFUNCTION EnumProcessModules(hProcess,@hMod,nSizeOf,@nBytesNeeded) ;
USING STDCALL FROM PSAPI.DLL
*****************************************************************************************************************************
***
*****************************************************************************************************************************
STATIC FUNCTION EnumerateProcessModules(nProcessHandle)
LOCAL nSize := 4096
LOCAL nReturned := 0
LOCAL nRetVal := 0
LOCAL nVal
LOCAL cModuleHandles := SPACE(4096)
LOCAL naHandleForProcess := {}
LOCAL nElements
LOCAL i
nRetVal:=EnumProcessModules(nProcessHandle,@cModuleHandles,nSize,@nReturned)
IF nRetVal # 0
nElements := nReturned / 4
FOR i := 1 TO nElements
nVal := BIN2U(SubStr(cModuleHandles, 4 * (i - 1) + 1, 4))
AAdd(naHandleForProcess,nVal)
NEXT
ENDIF
RETURN(naHandleForProcess)
*****************************************************************************************************************************
***
*****************************************************************************************************************************
#INCLUDE "OS.CH"
STATIC FUNCTION WinNT()
RETURN(OS(OS_FAMILY) == "WINNT")
*****************************************************************************************************************************
***
*****************************************************************************************************************************
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Programm bereits gestartet ?
hi,
ich habe auch so was früher benutzt, aber "soviel" Code muss nicht sein ...das tut es auch.
Bemerkung : es wird nach dem Dialog:Title "gesucht"
ich habe auch so was früher benutzt, aber "soviel" Code muss nicht sein ...
Code: Alles auswählen
PROCEDURE AppSys
LOCAL cTitle := "Xbase++ NeroCOM"
LOCAL hWndDlg := DllCall("User32.dll",DLL_STDCALL,"FindWindowA",0,cTitle)
IF !(hWndDlg == 0)
DllCall("User32.dll",DLL_STDCALL,"SetForegroundWindow",hWndDlg)
DllCall("User32.dll",DLL_STDCALL,"BringWindowToTop",hWndDlg)
DllCall("User32.dll",DLL_STDCALL,"ShowWindow",hWndDlg,1)
DllCall("User32.dll",DLL_STDCALL,"UpdateWindow",hWndDlg)
*** It is a second instance.... Bye Bye
QUIT
ENDIF
Return
Bemerkung : es wird nach dem Dialog:Title "gesucht"
gruss by OHR
Jimmy
Jimmy