Hallo Entwickler Gemeinde,
habe das Beispiel von Hr.Kosch Bildschirminhalt einer DOS-Anwendung auslesen #3 - Andreas Kosch 10.10.2003 7:02
<a href="/webx?13@@.2cb7d084/2">Andreas Kosch "Bildschirminhalt einer DOS-Anwendung auslesen" 10.10.2003 07:02</a>
verwendet.
Bei einer "Form-Anwendung" gibt es da auch keine Probleme, aber wenn ich den Code in einem Windows Dienst verwende, erhält das Programm keinen gültigen "Exit-Code" und bleibt in der repeat-Schleife hängen.
Ersetze ich "Repeat ... Until" durch
"WaitForSingleObject(aPI.hProcess, 2000);"
habe ich zwar dieses Problem nicht mehr, aber dafür kann ich nicht mehr auf die Datei zugreifen, die mir den Inhalt des Dos-Fensters ausgibt.
Als Fehler erhalte ich im WindowsEventViewer:
"The process cannot access the file because it is being used by another process."
Ich schliesse darauf, dass mit oben geänderten Code und "CloseHandle" der Prozess trotzdem noch aktiv ist, also muss ich wieder zur Repeat-Schleife zurück. Aber warum erhalte ich keinen gültigen Exit-Code, ausser "STILL_ACTIVE"? (Wie gesagt, nur wenn es aus einem Windows-Dienst ausgeführt wird).
Für jede Hilfe bin ich dankbar!!!
Hier noch der Code:
<PRE>
function SYSCommand(SCommand: PChar): AnsiString;
var
aSA : TSecurityAttributes;
aSI : TStartupInfo;
aPI : TProcessInformation;
szTemp : array[0..199] of Char;
FName : String;
hLogFile : THandle;
dwExit : DWORD;
begin
FillChar(aSA, SizeOf(aSA), #0);
aSA.nLength := SizeOf(aSA);
aSA.bInheritHandle := True;
// temp. Dateinamen für Output generieren
FillChar(szTemp, SizeOf(szTemp), #0);
GetEnvironmentVariable(PCHar('TEMP'), szTemp, 180);
// FName := szTemp + '\temp.txt';
FName := 'd:\export\temp.txt';
// Output-Datei öffnen
hLogFile := CreateFile(PCHar(FName), GENERIC_WRITE or GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
@aSA, CREATE_ALWAYS, 0, 0);
// Standard-Output in Datei umleiten
GetStartupInfo(aSI);
aSI.dwflags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
aSI.wShowWindow := SW_HIDE;
aSI.hStdOutput := hLogFile;
if CreateProcess(nil,SCommand, nil, nil, True,
NORMAL_PRIORITY_CLASS,
nil, nil, aSI, aPI) then begin
// repeat
// Forms.Application.ProcessMessages;
// GetExitCodeProcess(aPI.hProcess, dwExit);
// until dwExit <> STILL_ACTIVE;
WaitForSingleObject(aPI.hProcess, 2000);
CloseHandle(aPI.hThread);
CloseHandle(aPI.hProcess);
CloseHandle(hLogFile);
result:= FName;
end else begin
result:= '';
end;
end;
...
begin
...
// Nach diesem Aufruf kommt die Fehlermeldung
im Eventviewer
TempFile.LoadFromFile(TempFileName);
...
end;
habe das Beispiel von Hr.Kosch Bildschirminhalt einer DOS-Anwendung auslesen #3 - Andreas Kosch 10.10.2003 7:02
<a href="/webx?13@@.2cb7d084/2">Andreas Kosch "Bildschirminhalt einer DOS-Anwendung auslesen" 10.10.2003 07:02</a>
verwendet.
Bei einer "Form-Anwendung" gibt es da auch keine Probleme, aber wenn ich den Code in einem Windows Dienst verwende, erhält das Programm keinen gültigen "Exit-Code" und bleibt in der repeat-Schleife hängen.
Ersetze ich "Repeat ... Until" durch
"WaitForSingleObject(aPI.hProcess, 2000);"
habe ich zwar dieses Problem nicht mehr, aber dafür kann ich nicht mehr auf die Datei zugreifen, die mir den Inhalt des Dos-Fensters ausgibt.
Als Fehler erhalte ich im WindowsEventViewer:
"The process cannot access the file because it is being used by another process."
Ich schliesse darauf, dass mit oben geänderten Code und "CloseHandle" der Prozess trotzdem noch aktiv ist, also muss ich wieder zur Repeat-Schleife zurück. Aber warum erhalte ich keinen gültigen Exit-Code, ausser "STILL_ACTIVE"? (Wie gesagt, nur wenn es aus einem Windows-Dienst ausgeführt wird).
Für jede Hilfe bin ich dankbar!!!
Hier noch der Code:
<PRE>
function SYSCommand(SCommand: PChar): AnsiString;
var
aSA : TSecurityAttributes;
aSI : TStartupInfo;
aPI : TProcessInformation;
szTemp : array[0..199] of Char;
FName : String;
hLogFile : THandle;
dwExit : DWORD;
begin
FillChar(aSA, SizeOf(aSA), #0);
aSA.nLength := SizeOf(aSA);
aSA.bInheritHandle := True;
// temp. Dateinamen für Output generieren
FillChar(szTemp, SizeOf(szTemp), #0);
GetEnvironmentVariable(PCHar('TEMP'), szTemp, 180);
// FName := szTemp + '\temp.txt';
FName := 'd:\export\temp.txt';
// Output-Datei öffnen
hLogFile := CreateFile(PCHar(FName), GENERIC_WRITE or GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
@aSA, CREATE_ALWAYS, 0, 0);
// Standard-Output in Datei umleiten
GetStartupInfo(aSI);
aSI.dwflags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
aSI.wShowWindow := SW_HIDE;
aSI.hStdOutput := hLogFile;
if CreateProcess(nil,SCommand, nil, nil, True,
NORMAL_PRIORITY_CLASS,
nil, nil, aSI, aPI) then begin
// repeat
// Forms.Application.ProcessMessages;
// GetExitCodeProcess(aPI.hProcess, dwExit);
// until dwExit <> STILL_ACTIVE;
WaitForSingleObject(aPI.hProcess, 2000);
CloseHandle(aPI.hThread);
CloseHandle(aPI.hProcess);
CloseHandle(hLogFile);
result:= FName;
end else begin
result:= '';
end;
end;
...
begin
...
// Nach diesem Aufruf kommt die Fehlermeldung
im Eventviewer
TempFile.LoadFromFile(TempFileName);
...
end;
Comment