Datei (.DLL, .EXE, .LNG, ...) prüfen [ERLEDIGT]
Moderator: Moderatoren
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Datei (.DLL, .EXE, .LNG, ...) prüfen [ERLEDIGT]
Guten Morgen,
im Rahmen von Programmupdates möchte ich im Vorfeld überprüfen, ob eine Datei von einer Applikation verwendet wird.
Dabei wäre es günstig dem User eine Liste von Applikationen anzuzeigen, die terminiert werden müssen, um das Update auszuführen.
Es gibt doch sicherlich eine API-Funktion (Win XP) mit der das machbar ist, oder?
Im Voraus schon vielen Dank,
Gerd
im Rahmen von Programmupdates möchte ich im Vorfeld überprüfen, ob eine Datei von einer Applikation verwendet wird.
Dabei wäre es günstig dem User eine Liste von Applikationen anzuzeigen, die terminiert werden müssen, um das Update auszuführen.
Es gibt doch sicherlich eine API-Funktion (Win XP) mit der das machbar ist, oder?
Im Voraus schon vielen Dank,
Gerd
Zuletzt geändert von Gerd König am Fr, 21. Mai 2010 6:05, insgesamt 1-mal geändert.
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
Hi,
da sich wahrscheinlich noch niemand mit der Problematik beschäftigt hat, werde ich jetzt (erst einmal) einen anderen Lösungsansatz verwenden
In meinem Updateordner sind alle möglichen Programmdateien vorhanden.
Da ich beim Start einer Applikation immer einen applikationsspezifischen Mutex generiere, werde ich vor der Ausführung eines Updates die Existenz der Mutexwerte zu allen möglichen Applikationen (*.exe im Updateordner) prüfen.
Ist kein Mutex vorhanden kann ich das Update ausführen.
Anderenfalls werde ich die Applikationen mit gültigen Mutex anzeigen und das Schließen dieser verlangen. Das ganze werde ich in einer Schleife verpacken, so daß das Update erst nach dem Schließen aller Applikationen ausgeführt wird.
Die Sache hat nur einen Schönheitsfehler:
Es müssen auch die XBase-Programme terminiert werden, welche die zu aktualisierende DLL gar nicht verwenden, aber damit kann ich (und muß der User ) leben!
Gerd
da sich wahrscheinlich noch niemand mit der Problematik beschäftigt hat, werde ich jetzt (erst einmal) einen anderen Lösungsansatz verwenden
In meinem Updateordner sind alle möglichen Programmdateien vorhanden.
Da ich beim Start einer Applikation immer einen applikationsspezifischen Mutex generiere, werde ich vor der Ausführung eines Updates die Existenz der Mutexwerte zu allen möglichen Applikationen (*.exe im Updateordner) prüfen.
Ist kein Mutex vorhanden kann ich das Update ausführen.
Anderenfalls werde ich die Applikationen mit gültigen Mutex anzeigen und das Schließen dieser verlangen. Das ganze werde ich in einer Schleife verpacken, so daß das Update erst nach dem Schließen aller Applikationen ausgeführt wird.
Die Sache hat nur einen Schönheitsfehler:
Es müssen auch die XBase-Programme terminiert werden, welche die zu aktualisierende DLL gar nicht verwenden, aber damit kann ich (und muß der User ) leben!
Gerd
- Jan
- Marvin
- Beiträge: 14659
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
Gerd,
mit der Problematik habe ich mich bis kurz vor dem Nervenzusammenbruch beschäftigt. Und habe jetzt frustriert eine "Krücke" bei mir eingebaut. Ich schriebe die Updatedateien in ein eigenes Verzeichnis. Wenn dann das Programm gestartet wird und sieht, daß in dem Verzeichnis Dateien drin stehen, dann wird das Programm beendet, eine Batchdatei aufgerufen, die die neuen Datein rüberkopiert, im Updateverteichnis löscht, und mein Programm wieder startet. Wie gesagt, eine Krücke. Und funktioniert auch nur, weil ich nur ein einziges Xbase++-Programm laufen lasse, allerdings bestehend aus einer .exe und einer handvoll .dll.
Jan
mit der Problematik habe ich mich bis kurz vor dem Nervenzusammenbruch beschäftigt. Und habe jetzt frustriert eine "Krücke" bei mir eingebaut. Ich schriebe die Updatedateien in ein eigenes Verzeichnis. Wenn dann das Programm gestartet wird und sieht, daß in dem Verzeichnis Dateien drin stehen, dann wird das Programm beendet, eine Batchdatei aufgerufen, die die neuen Datein rüberkopiert, im Updateverteichnis löscht, und mein Programm wieder startet. Wie gesagt, eine Krücke. Und funktioniert auch nur, weil ich nur ein einziges Xbase++-Programm laufen lasse, allerdings bestehend aus einer .exe und einer handvoll .dll.
Jan
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.
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
Hallo Jan,
meine "Krücke" sieht momentan beim Start einer Applikation im Falle eines Updates so aus:
Ich fange an alle relevanten Dateien vom Server (Updateordner) auf die Festplatte der Arbeitsstation zu kopieren, bis ich auf eine Date stoße, die ich nicht kopieren kann.
Das ist für mich das Zeichen, daß es noch mindestens eine aktive EXE auf der Arbeitsstation gibt, die diese verwendet. Dann breche ich das Update ab, mit der lapidaren Meldung, daß alle relevanten Applikationen zu terminieren sind (natürlich etwas user-freundlicher formuliert).
Nun bleibt es dem User überlassen, welche Programme zu schließen sind! Manche haben daraufhin Windows neu gestartet (führt ja auch zur Lösung des Updateproblems)
Herzlich
Gerd
meine "Krücke" sieht momentan beim Start einer Applikation im Falle eines Updates so aus:
Ich fange an alle relevanten Dateien vom Server (Updateordner) auf die Festplatte der Arbeitsstation zu kopieren, bis ich auf eine Date stoße, die ich nicht kopieren kann.
Das ist für mich das Zeichen, daß es noch mindestens eine aktive EXE auf der Arbeitsstation gibt, die diese verwendet. Dann breche ich das Update ab, mit der lapidaren Meldung, daß alle relevanten Applikationen zu terminieren sind (natürlich etwas user-freundlicher formuliert).
Nun bleibt es dem User überlassen, welche Programme zu schließen sind! Manche haben daraufhin Windows neu gestartet (führt ja auch zur Lösung des Updateproblems)
Herzlich
Gerd
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
Hallo Gerd,
warum nicht im Updateordner eine Version.txt hinterlegen.
Die Exe prüft beim Start anhand der eigenen Version, ob diese älter als die im Updateordner ist.
Wenn die im Updateordner neuer ist, Programm erst gar nicht starten, sondern Meldung anzeigen,
dass das Programm beendet wird und nach dem Ende neu gestartet werden muss.
Das wäre meines Erachtens die einfachste Lösung.
Die Lösung von Jan funktioniert nur wenn es eine Einzelplatzanwendung ist.
warum nicht im Updateordner eine Version.txt hinterlegen.
Die Exe prüft beim Start anhand der eigenen Version, ob diese älter als die im Updateordner ist.
Wenn die im Updateordner neuer ist, Programm erst gar nicht starten, sondern Meldung anzeigen,
dass das Programm beendet wird und nach dem Ende neu gestartet werden muss.
Das wäre meines Erachtens die einfachste Lösung.
Die Lösung von Jan funktioniert nur wenn es eine Einzelplatzanwendung ist.
Gruß
Klaus
Klaus
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
@Koverhage
Im Updateordner befinden sich ca. 20 EXE-Files, ca. 40 DLLs und diverse andere.
Dabei handelt es sich immer um das aktuelle Programmpaket.
Wir haben über 100 Arbeitsstationen, auf denen immer nur einige der vorhandenen Applikationen laufen.
Alle Programme werden über einen Loader gestartet.
Dieser überprüft, ob z.B. DLLs aktualisiert werden müssen.
Ist das der Fall, wird die entsprechende Datei kopiert.
Das Problem dabei ist folgendes:
Es wurde das Programm APP1.EXE gestartet. Dieses Programm benötigt u.a. die LIB1.DLL.
Während das Programm APP1.EXE bereits läuft, wird eine neue Version von LIB1.DLL in den Updateordner gestellt.
Jetzt soll das Programm APP2.EXE gestartet werden.
Die bisherige Loader-Version stellt fest, daß die LIB1.DLL aktualisiert werden soll. Der Kopiervorgang scheitert jedoch,
da LIB1.DLL durch das Programm APP1.EXE gesperrt ist.
In diesem Fall bringe ich eine Meldung, daß alle Applikationen zu beenden und danach neu zu starten sind.
Der Vorgang wird abgebrochen.
Ein Start weiterer Applikationen ist damit nicht möglich!
Jetzt will ich den Loader dahingehend ändern, daß festgestellt wird welche von den zu aktualisierenden DLLs durch laufende Programme
bereits gesperrt sind.
In diesem Fall könnte ich z.B. auf das Beenden von APP1.EXE verzichten und APP2.EXE auf Wunsch (Confirmbox mit 3 Tasten) ohne Update
von LIB1.DLL starten.
Das Update würde erst dann zwangsweise ausgeführt, wenn keine relevante Applikation gestartet wurde.
Gerd
Im Updateordner befinden sich ca. 20 EXE-Files, ca. 40 DLLs und diverse andere.
Dabei handelt es sich immer um das aktuelle Programmpaket.
Wir haben über 100 Arbeitsstationen, auf denen immer nur einige der vorhandenen Applikationen laufen.
Alle Programme werden über einen Loader gestartet.
Dieser überprüft, ob z.B. DLLs aktualisiert werden müssen.
Ist das der Fall, wird die entsprechende Datei kopiert.
Das Problem dabei ist folgendes:
Es wurde das Programm APP1.EXE gestartet. Dieses Programm benötigt u.a. die LIB1.DLL.
Während das Programm APP1.EXE bereits läuft, wird eine neue Version von LIB1.DLL in den Updateordner gestellt.
Jetzt soll das Programm APP2.EXE gestartet werden.
Die bisherige Loader-Version stellt fest, daß die LIB1.DLL aktualisiert werden soll. Der Kopiervorgang scheitert jedoch,
da LIB1.DLL durch das Programm APP1.EXE gesperrt ist.
In diesem Fall bringe ich eine Meldung, daß alle Applikationen zu beenden und danach neu zu starten sind.
Der Vorgang wird abgebrochen.
Ein Start weiterer Applikationen ist damit nicht möglich!
Jetzt will ich den Loader dahingehend ändern, daß festgestellt wird welche von den zu aktualisierenden DLLs durch laufende Programme
bereits gesperrt sind.
In diesem Fall könnte ich z.B. auf das Beenden von APP1.EXE verzichten und APP2.EXE auf Wunsch (Confirmbox mit 3 Tasten) ohne Update
von LIB1.DLL starten.
Das Update würde erst dann zwangsweise ausgeführt, wenn keine relevante Applikation gestartet wurde.
Gerd
- AUGE_OHR
- Marvin
- Beiträge: 12911
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
hi,
wenn es um "geladene" Xbase++ DLL geht :ich gehe also durch DIRECTORY( "*.DLL" ) jede einzelne DLL an und stelle fest ob sie geladen wurde wobei ich die Runtime DLL im selben Verzeichnis wie die *.EXE habe
wenn es um "geladene" Xbase++ DLL geht :
Code: Alles auswählen
PROCEDURE DLLLIST()
LOCAL I, J, DllName, hDll, aVersion, fVersion
LOCAL aDLLFiles := DIRECTORY( "*.DLL" ) // hier nur aktuelles Verzeichniss
LOCAL nCount := LEN( aDLLFiles )
LOCAL n, nSum, cTest, cVers := ""
LOCAL DllList := {}
FOR n := 1 TO nCount
AADD( DllList, aDLLFiles[ n, F_NAME ] )
NEXT
FOR I := 1 TO LEN( DllList )
DllName := DllList[ I ]
IF DllInfo( DllName, DLL_INFO_LOADED )
hDll := DllInfo( DllName, DLL_INFO_HANDLE )
fVersion := LoadResource( 1, hDll, RES_VERSIONFIXED )
aVersion := LoadResource( 1, hDll, RES_VERSION )
* ? ""
* ? Replicate( "-", 78 )
* ? ""
* ? DllName
IF LEN( fVersion ) > 0
* ? "Product Version:"+ltrim(str(fVersion[RES_PRODVER_MS]))+ltrim(str(fVersion[RES_PRODVER_LS ]))
* ? " File Version:"+ltrim(str(fVersion[RES_FILEVER_MS]))+ltrim(str(fVersion[RES_FILEVER_LS ]))
* ? " File Time:"+ltrim(str(fVersion[RES_FILETIME_MS]))+ltrim(str(fVersion[RES_FILETIME_LS]))
ELSE
ENDIF
IF LEN( aVersion ) > 0
FOR J := 1 TO LEN( aVersion )
cTest := aVersion[ J ] [ RES_VERSION_KEY ]
DO CASE
CASE cTest = "CompanyName"
CASE cTest = "InternalName"
CASE cTest = "LegalCopyright"
CASE cTest = "OriginalFilename"
CASE cTest = "ProductName"
CASE cTest = "ProductVersion"
CASE cTest = "Comment"
CASE cTest = "FileVersion"
cVers := aVersion[J][RES_VERSION_VALUE]
OTHERWISE
// FileDescription
* ? aVersion[J][RES_VERSION_KEY]+": "+aVersion[J][RES_VERSION_VALUE]
? SUBSTR(DllName+SPACE(15),1,15) + ": " +;
LTRIM( LTRIM( cVers )+" "+ LTRIM( aVersion[J][RES_VERSION_VALUE] ) )
ENDCASE
NEXT
ELSE
ENDIF
ENDIF
NEXT
RETURN
gruss by OHR
Jimmy
Jimmy
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
Hallo Jimmy,
die von dir genannte Funktionalität verwende ich um die Datei-Versionen anzuzeigen.
Damit habe ich allerdings noch nicht die zugehörigen auf dieser Maschine gestarteten Programme.
Jetzt habe ich noch folgende Idee:
Ich starte aus dem Loader das Kommando "tasklist /M" und lenke die Ausgabe in eine Datei diese lese ich dann ein und kann den Gesamtstring mit einem Parser analysieren.
Einen Schönheitsfehler hat das Ganze:
Ich erhalte keine Information z.B. über geöffnete .lng-Dateien (von List&Label)
Das sollte aber kein Problem sein, da zumindest die XBase-Runtime und auf jedenfall einige meiner DLLs geladen sind.
Jedenfalls kann ich dann prüfen, welche Programme zu beenden sind, um ein DLL-Update zu starten.
Man könnte noch soweit gehen, die entsprechenden Prozesse programmtechnisch zu killen.
Da das Kommando "tasklist" letztendlich auch nur auf die Windows-API zurückgreift, gibt es sicherlich auch eine Möglichkeit, den Umweg über eine Datei zu vermeiden.
Gerd
die von dir genannte Funktionalität verwende ich um die Datei-Versionen anzuzeigen.
Damit habe ich allerdings noch nicht die zugehörigen auf dieser Maschine gestarteten Programme.
Jetzt habe ich noch folgende Idee:
Ich starte aus dem Loader das Kommando "tasklist /M" und lenke die Ausgabe in eine Datei diese lese ich dann ein und kann den Gesamtstring mit einem Parser analysieren.
Einen Schönheitsfehler hat das Ganze:
Ich erhalte keine Information z.B. über geöffnete .lng-Dateien (von List&Label)
Das sollte aber kein Problem sein, da zumindest die XBase-Runtime und auf jedenfall einige meiner DLLs geladen sind.
Jedenfalls kann ich dann prüfen, welche Programme zu beenden sind, um ein DLL-Update zu starten.
Man könnte noch soweit gehen, die entsprechenden Prozesse programmtechnisch zu killen.
Da das Kommando "tasklist" letztendlich auch nur auf die Windows-API zurückgreift, gibt es sicherlich auch eine Möglichkeit, den Umweg über eine Datei zu vermeiden.
Gerd
- AUGE_OHR
- Marvin
- Beiträge: 12911
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Datei (.DLL, .EXE, .LNG, ...) prüfen
yupGerd König hat geschrieben:Da das Kommando "tasklist" letztendlich auch nur auf die Windows-API zurückgreift, gibt es sicherlich auch eine Möglichkeit, den Umweg über eine Datei zu vermeiden.
Code: Alles auswählen
#define WM_CLOSE 0x0010
#define WM_QUIT 0x0012
FUNCTION CloseIt( aName )
LOCAL i, nMax
nMax := LEN( aName )
FOR i = 1 TO nMax
CloseNow( aName[ i ] )
NEXT
RETURN NIL
FUNCTION CloseNow( cName )
LOCAL oDlg
LOCAL aTasklist
LOCAL aSize := { 0, 0 }
LOCAL aPos := { 0, 0 }
LOCAL lRunnin := .F.
LOCAL i
LOCAL nHwnd, cWind
oDlg := XBPDIALOG() :new( APPDESKTOP(),, aPos, aSize,, .F. )
oDlg:clipSiblings := .T.
oDlg:drawingArea:ClipChildren := .T.
oDlg:create()
SETAPPFOCUS( oDlg )
aTasklist := GetTaskList( oDlg:gethWnd() )
FOR i = 1 TO LEN( aTasklist )
cWind := TRIM( UPPER( SUBSTR( aTasklist[ i ], 9 ) ) )
cWind := SUBSTR( cWind, 1, LEN( cWind ) - 1 )
IF cWind == TRIM( UPPER( cNaam ) )
lRunnin := .T.
nHwnd := VAL( LEFT( aTasklist[ i ], 8 ) )
SendMessageA( nHwnd, WM_CLOSE, 0, 0 ) // evtl WM_QUIT
RETURN lRunnin
ENDIF
NEXT
RETURN lRunnin
FUNCTION gettasklist( hWnd )
LOCAL aList := {}
LOCAL cWindowName
LOCAL nVisible
DO WHILE hWnd != 0
cWindowname := SPACE( 100 )
IF ( getwindowtexta( hWnd, @cWindowName, LEN( cWindowName ) ) <> 0 )
nVisible := IsWindowVisible( hWnd )
IF nVisible == 1
AADD( aList, STR( hWnd, 8 ) + cWindowname )
ENDIF
ENDIF
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
ENDDO
RETURN aList
FUNCTION GetWindow( hWnd, uCmd )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindow", hWnd, uCmd )
DllUnLoad( nDll )
RETURN xRet
FUNCTION GetWindowTextA( hWnd, lPstring, nMax )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindowTextA", hWnd, @lPstring, nMax )
DllUnLoad( nDll )
RETURN xRet
FUNCTION IsWindowVisible( hWnd )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "IsWindowVisible", hWnd )
DllUnLoad( nDll )
RETURN xRet
gruss by OHR
Jimmy
Jimmy
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda