Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Probleme von ShellExecute unter Win2003 Server 64 Bit (https://www.delphipraxis.net/112856-probleme-von-shellexecute-unter-win2003-server-64-bit.html)

BrinkschulteManfred 28. Apr 2008 13:16


Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Hallo zusammen,

habe mir eine kleine GUI geschrieben, die ein Programm mit entsprechenden Parametern Kommandozeilenparametern aufruft. Dieses Programm funktioniert unter XP und Windows 2003 jeweils ihn der 32 Bit Version gut. Unter 64 Bit 2003 Server wird das externe Prograjmm aber nicht zeitgesteuert gestartet. Es kommt auch zu keiner Fehlermeldung. Muss man ShellExecute unter Win2003/64 anders (mit anderen Werten) nutzen, damit es funktioniert? Sollte man eventuell anstatt ShellExecute anders programmieren?

Beste Grüße
Manfred

Assertor 28. Apr 2008 13:25

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Du versuchst aber nicht, eine 16bit Anwendung zu starten, oder?

Bernhard Geyer 28. Apr 2008 13:35

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Wie ist der Rückgabeparameter/Fehlercode von ShellExecute?

BrinkschulteManfred 28. Apr 2008 14:41

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Zitat:

Zitat von Assertor
Du versuchst aber nicht, eine 16bit Anwendung zu starten, oder?

Ich denke nicht, das NTBackup.exe der jeweiligen Installation eine 16 Bit Anwendung ist :?


Zitat:

Zitat von Bernhard Geyer
Wie ist der Rückgabeparameter/Fehlercode von ShellExecute?

Der Rückgabewert ist 2 auf dem 64 Bit System und 42 auf dem 32 Bit System.

Bernhard Geyer 28. Apr 2008 14:47

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Zitat:

Zitat von BrinkschulteManfred
Zitat:

Zitat von Bernhard Geyer
Wie ist der Rückgabeparameter/Fehlercode von ShellExecute?

Der Rückgabewert ist 2 auf dem 64 Bit System und 42 auf dem 32 Bit System.

#define ERROR_FILE_NOT_FOUND 2L -> Ich denke du nimmst den Falschen Pfad (WOW-Dateisystemvirtualisierung)

pertzschc 28. Apr 2008 14:50

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Zitat:

Zitat von BrinkschulteManfred
Zitat:

Zitat von Bernhard Geyer
Wie ist der Rückgabeparameter/Fehlercode von ShellExecute?

Der Rückgabewert ist 2 auf dem 64 Bit System und 42 auf dem 32 Bit System.

Schau mal hier: Link

Gruß,
Christoph

BrinkschulteManfred 28. Apr 2008 15:05

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Wenn ich das richtig interpretiere, dann heißt dies, dass die Datei nicht gefunden wird, oder?

Ich habe aber sowohl
Delphi-Quellcode:
ShellExecute(handle, 'open', 'NTBackup.exe', AufrufAsPChar, '', SW_Shownormal);
als auch
Delphi-Quellcode:
ShellExecute(handle, 'open', 'C:\windows\system32\NTBackup.exe', AufrufAsPChar, '', SW_Shownormal);
ausprobiert. Der Pfad stimmt aber trotzdem kommt der Fehlerwert 2. :(

Bernhard Geyer 28. Apr 2008 15:12

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Du bekommst als Win32 unter Win64 andere Verzeichnisse untergeschoben als du im Windows Explorer siehst.
System32 wird irgendwie als SysWOW32 umgebogen und dort wird das 64-Bit NTBackup.exe nicht liegen.

BrinkschulteManfred 29. Apr 2008 08:19

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Danke Bernhard,

das hört sich doch schon mal gut an. Aber warum findet er dann die NTBackup.Exe nicht, wenn ich sie ohne Pfad aufrufe, also Variante 1 ?

Luckie 29. Apr 2008 08:25

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Weil unter 64-Bit Windows eben die Pfade umgebogen werden.

BrinkschulteManfred 5. Mai 2008 10:53

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
So, es ist wieder Montag, ich bin im Büro :-( und beantworte mal die Antworten auf meine Frage:

Eventuell habe ich da etwas falsch verstanden, aber denn doch die Pfade nur virtuell sind und im System eigentlich anders vorliegen...

1. Wozu dann das ganze, wenn kan dann nicht über die virtuellen Pfade zugreifen kann?
2. In der guten alten DOS-Box kann ich doch auch ohne eine Pfadangabe NTBackup.exe aufrufen und das Programm wird gestartet. Warum klappt dies dann nicht unter Win2003/64, wenn es unter Win2003/32 ohne Probleme geht? Wie gesagt, sowohl in Variante 1 als auch Variante 2 funktioniert es nicht...

Hat noch jemand Ideen, wie ich das lösen kann? :?:

Vjay 5. Mai 2008 13:07

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
NTBackup in ein anderes Verzeichnis kopieren?

BrinkschulteManfred 5. Mai 2008 13:31

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
:thumb:

Das ist zwar nicht schön :wink: aber funktioniert :thumb:

Wenn es keine besseren Vorschläge mehr gibt, dann werde ich es so lassen ...

Besten Dank
:thumb:


PS: Habe gerade ausprobiert, ob es auch ohne feste Pfadangabe funktioniert, wenn die NTBackup.exe im selben Verzeichnis wie mein Programm liegt. Auch das geht ...!

Klaus01 5. Mai 2008 13:35

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
.. oder einen Pfad zu NTBackup legen.

Grüße
Klaus

BrinkschulteManfred 5. Mai 2008 13:42

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Standardmäßig liegt diese unter C:\Windows\System32\ und man kann diese von egal wo aufrufen, daher sollte der Pfad schon existieren :-(

Luckie 5. Mai 2008 13:43

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Zitat:

Zitat von BrinkschulteManfred
Wenn es keine besseren Vorschläge mehr gibt, dann werde ich es so lassen ...

Ich meine man könnte das "Umbiegen" mit Hilfe eines entsprechenden Manifestes unterbinden. Aber die sauberste Lösung wäre natürlich eine 64-Bit Anwendung zu schreiben, wenn 64-Bit die Zielplattform ist.

nicodex 5. Mai 2008 14:40

Re: Probleme von ShellExecute unter Win2003 Server 64 Bit
 
Man kann versuchen die File System Redirection des WOW64-"Emulators" für den Aufruf zu deaktivieren.
Delphi-Quellcode:
function Wow64DisableWow64FsRedirection(out AOldValue: Pointer): BOOL; stdcall;
type
  TFNRealApiProc = function(out AOldValue: Pointer): BOOL; stdcall;
const
  RealApiName = 'Wow64DisableWow64FsRedirection';
{$WRITEABLECONST ON}
const
  Initialized: Integer = 0;
  RealApiProc: TFNRealApiProc = nil;
{$WRITEABLECONST OFF}
begin
  if Initialized = 0 then
  begin
    RealApiProc := TFNRealApiProc(GetProcAddress(GetModuleHandle(kernel32),
      RealApiName));
    InterlockedIncrement(Initialized);
  end;
  if Assigned(RealApiProc) then
    Result := RealApiProc(AOldValue)
  else
  begin
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    Result := False;
  end;
end;

function Wow64RevertWow64FsRedirection(AOldValue: Pointer): BOOL; stdcall;
type
  TFNRealApiProc = function(AOldValue: Pointer): BOOL; stdcall;
const
  RealApiName = 'Wow64RevertWow64FsRedirection';
{$WRITEABLECONST ON}
const
  Initialized: Integer = 0;
  RealApiProc: TFNRealApiProc = nil;
{$WRITEABLECONST OFF}
begin
  if Initialized = 0 then
  begin
    RealApiProc := TFNRealApiProc(GetProcAddress(GetModuleHandle(kernel32),
      RealApiName));
    InterlockedIncrement(Initialized);
  end;
  if Assigned(RealApiProc) then
    Result := RealApiProc(AOldValue)
  else
  begin
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    Result := False;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
const
  FileName = 'sigverif.exe';
var
  ExecCode: Integer;
  RevertFs: BOOL;
  OldValue: Pointer;
  MsgText: string;
begin
  ExecCode := E_UNEXPECTED;
  RevertFs := False;
  try
    ExecCode := Integer(ShellExecute(Handle, nil, FileName, nil, nil, SW_SHOW));
    case ExecCode of
      ERROR_FILE_NOT_FOUND,
      ERROR_PATH_NOT_FOUND,
      SE_ERR_DLLNOTFOUND:
        begin
          RevertFs := Wow64DisableWow64FsRedirection(OldValue);
          if RevertFs then
            ExecCode := Integer(
              ShellExecute(Handle, nil, FileName, nil, nil, SW_SHOW));
        end;
    end;
  finally
    if RevertFs then
      Wow64RevertWow64FsRedirection(OldValue);
  end;
  MsgText :=
    'ShellExecute: $' + IntToHex(ExecCode, 8) + ' (' + IntToStr(ExecCode) +
    ')'#13#10'FsRedirected: ' + BoolToStr(RevertFs, True);
  if ExecCode <= 32 then
    MsgText := MsgText + #13#10#13#10 + SysErrorMessage(ExecCode);
  ShowMessage(MsgText);
end;
Allerdings kann es diverse Probleme geben (Falls die API intern einen neuen Thread erzeugt, dann 'erbt' dieser nicht den Status der File System Redirection. Und falls die API intern DLLs laden muss (32-bit), dann wird dies fehlschlagen, da die 64-Bit DLLs gefunden werden).

Wie Luckie bereits erwähnte, besteht die 'saubere' Lösung aus einer nativen (64-Bit) Version deines Programms (oder der Nutzung eines nativen out-of-process (COM-)Objekts).


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz