AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Datei ausführen unter Windows 64-Bit
Thema durchsuchen
Ansicht
Themen-Optionen

Datei ausführen unter Windows 64-Bit

Ein Thema von Rakshasa · begonnen am 18. Feb 2007 · letzter Beitrag vom 2. Apr 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#1

Datei ausführen unter Windows 64-Bit

  Alt 18. Feb 2007, 17:56
Hallo Leute,

unter Windows64 ist der FileSystemRedirector aktiv, der Anfragen von 32-Bit Programmen umleitet, bsp. "sieht" eine 32-Bit-Anwendung nur den Inhalt des Ordners "Windows\SysWow64\..." während 64-Bit-Anwendungen den Ordner "Windows\System32" sehen.
Nachlesen Problematisch wird dies, wenn eine 32-Bit-Anwendung eine 64-Bit-Anwendung ausführen will.

Mein Programm soll unter Win64 die Datei "regedit.exe" ausführen. Von dieser Datei existieren 2 Varianten: Eine C:\Windows\regedit.exe und eine C:\windows\syswow64\regedit.exe. Wenn mein (32-Bit) Programm nun ShellExecute ausführt, wird immer nur die 32-Bit Variante ausgeführt. Ich will aber die 64-Bit-Variante ausführen... Ist halt schlecht, da z.B. 32-Bit-RegEdit keine 64-Bit-Schlüssel sehen kann.

Umgehen kann man das nach MS durch bestimmte Flags, etwa "Wow64DisableWow64FsRedirection" oder "Wow64EnableWow64FsRedirection", welche wohl vor API calls gesetzt werden müssen.

MS hat hier was dazu geschrieben, leider schaffe ich es nicht mal annähern, den Code in Delphi umzusetzen ... hat da jemand eine Idee??
  Mit Zitat antworten Zitat
Benutzerbild von TonyR
TonyR

Registriert seit: 17. Jun 2006
Ort: Bautzen
503 Beiträge
 
FreePascal / Lazarus
 
#2

Re: Datei ausführen unter Windows 64-Bit

  Alt 18. Feb 2007, 18:47
Code:
#define _WIN32_WINNT 0x0501
#include <windows.h>

    PVOID OldValue;
    HANDLE hFile;

    BOOL bRet = Wow64DisableWow64FsRedirection (&OldValue);

    if (bRet == TRUE)
    {
        // Open a file
       
        hFile = CreateFile(TEXT("c:\\windows\\system32\\notepad.exe"),
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

        // Restore the previous WOW64 file system redirection value.
 
        Wow64RevertWow64FsRedirection (OldValue);
    }
   
    if( INVALID_HANDLE_VALUE != hFile )
    {
        // Use the file handle
    }
Also wenn ich das richtig verstehe, dann wird hier (ich weis nicht was PVOID für ein Daten-Typ sein soll) in "OldValue" mithilfe von der Funktion "Wow64DisableWow64FsRedirection" der Ursprungszustand gespeichert, wenn das geglückt ist, dann wird die Datei einfach nur aufgerufen (sozusagen dem shellexecute entsprechend, bloß eben mit dem Umweg erst ein Handle der Datei zu bekommen und danach erst die Datei zu öffnen) und danach wird das mit dem Umleiten wieder auf den Ursprungswert zurückgesetzt!
Das erscheint mir eigentlich ganz einleuchtend...
Aber wie man diese Redirection-Funktion in Delphi verwendet (bzw. weis ich gar nicht ob es die da gibt) hab ich keine Ahnung. Weil mir C++ hab ich mich noch nie beschäftigt, aber es gibt hier im Forum glaub ich ein paar die das mal "übersetzen" könnten...
Es ist unmöglich, witzig zu sein ohne ein bisschen Bosheit. Die Bosheit eines guten Witzes ist der Widerhaken, der ihn haften lässt. - Georg Christoph Lichtenberg
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Datei ausführen unter Windows 64-Bit

  Alt 19. Feb 2007, 12:44
Ja, vielleicht ist hier ja ein "C-ler", der eine kurze Übersetzung des Codes probieren könnte ...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.067 Beiträge
 
Delphi 12 Athens
 
#4

Re: Datei ausführen unter Windows 64-Bit

  Alt 19. Feb 2007, 13:05
zwar kein alter C-ler, aber dennoch ein grober Versuch?

mit Hilfe von:
MSDN-Library durchsuchenWow64DisableWow64FsRedirection
MSDN-Library durchsuchenWow64RevertWow64FsRedirection

Delphi-Quellcode:
Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  External 'Kernel32.dllName 'Wow64DisableWow64FsRedirection';
Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  External 'Kernel32.dllName 'Wow64EnableWow64FsRedirection';

Var Wow64FsEnableRedirection: LongBool;

Begin
  If Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection) Then Begin
    If ShellExecute(0, nil, PChar('c:\windows\system32\notepad.exe'), nil, nil, 0) = 0 Then
      Error...
    Wow64RevertWow64FsRedirection(Wow64FsEnableRedirection);
  End Else Error...
End;
Die (aufgehobene) Umleitung sollte doch wohl auch auf ShellExecute eine Auswirkung haben.

[add] ungetestet!
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 01:00
Zitat von himitsu:
zwar kein alter C-ler, aber dennoch ein grober Versuch?
........
Die (aufgehobene) Umleitung sollte doch wohl auch auf ShellExecute eine Auswirkung haben.
[add] ungetestet!
Hallo,

besten Dank Himitsu, es hat super geklappt!!!
(Bis auf eine kleine Änderung: Du hast
Wow64RevertWow64FsRedirection(Wow64FsEnableRedirection); geschrieben; ich hab das zu einem
Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection); geändert)
Ich habe das Ganze in eine kleine Function gepackt, diese überprüft mittels IsWin64, ob ein 64-Bit-Windows vorliegt oder nicht und führt das dementsprechend dann aus. Habe leider keine Möglichkeit, das auf Win32 zu testen; vielleicht kann das ja mal jemand machen und hier ein kleines Feedback posten?!
Wenn jemand was Schöneres für isWin64() hat, möge er es ebenfalls posten...

Delphi-Quellcode:

uses ShellApi, Registry, Windows;

Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
 External 'Kernel32.dllName 'Wow64DisableWow64FsRedirection';
Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
 External 'Kernel32.dllName 'Wow64EnableWow64FsRedirection';
Var Wow64FsEnableRedirection: LongBool;

....

Function FileExec(const sDatei: String): Integer;
 Function IsWin64: Boolean;
 begin
  With TRegistry.Create do begin
   RootKey := HKEY_LOCAL_MACHINE;
   Result := KeyExists('\SOFTWARE\Wow6432Node');
   Free;
  end;
 end;
begin

if isWin64 then begin

 If Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection) Then Begin
  Result := ShellExecute(0, nil, PChar(sDatei), nil, nil, 0);
  Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);
 End else
 Result := ShellExecute(0, nil, PChar(sdatei), nil, nil, 0);

end else
 Result := ShellExecute(0, nil, PChar(sdatei), nil, nil, 0);

end;
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 10:20
Hallo,

das klappt bei mir irgendwie nicht. Kompilieren kann ich das unter Win32 problemlos, doch beim Ausführen springt der Debugger zum "begin" in der Project.dpr. Spaßeshalber wollte ich dann mit F8 schauen, ob's irgendwie weitergeht, doch dann kommt:

Code:
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt D:\Eigene Dateien\Borland Studio-Projekte\Project1.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x7c947a50: write of address 0x00030d24'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  
---------------------------
Anschließend öffnet sich das CPU-Fenster und markiert ist diese Zeile:

Code:
7C947A50 56               push esi
OS: Win XP Pro SP2,32 Bit
Benutzerrechte: Sowohl eingeschränkt, als auch Admin. Beides mal der gleiche Fehler.
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 11:52
Zitat von Matze:
Hallo,

das klappt bei mir irgendwie nicht. Kompilieren kann ich das unter Win32 problemlos, doch beim Ausführen springt der Debugger zum "begin" in der Project.dpr. Spaßeshalber wollte ich dann mit F8 schauen, ob's irgendwie weitergeht, doch dann kommt:
Hö?! Das ist aber ziemlich seltsam, da durch den Code
Code:
 if isWin64 then begin
eigentlich nur der normale ShellExecute() Teil unter Win32 ausgeführt werden sollte ... vielleicht stimmt ja mit ShellExecute was nicht? Oder meint ihr, der Fehler wird durch die Aufrufe
Code:
Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
External 'Kernel32.dll' Name 'Wow64DisableWow64FsRedirection';
Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
External 'Kernel32.dll' Name 'Wow64EnableWow64FsRedirection';
Var Wow64FsEnableRedirection: LongBool;
verursacht? Jetzt bin ich etwas verwirrt ...
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 12:49
So, jetzt bin ich weniger verwirrt. Habe meine VMWare zum Laufen bekommen und konnte das Ganze auf Win32 (XP, SP2) testen. Dabei trat bei mir der Fehler auf, dass schon die Functionen der kernel32.dll einen Fehler beim Starten des Programms verursacht haben, da diese bei WIn32 fehlen. Auch hat die "0" bei ShellExecute (letzt Parameter) dazu geführt, das RegEdit unsichtbar startet - dies war bei Win64 (Vista) komischerweise nicht der Fall, anscheinend dürften hier Applikatione nicht mehr unsichtbar sein oder so.

Fazit: Habe das Ganze also dynamisch eingebunden und dabei ist folgende Function() herausgekommen; bei mir funktionierte alles unter Win XP32 und Vista 64-Bit tadellos.

Delphi-Quellcode:

uses ShellApi, Windows, Registry;

....

Function FileExec(const sDatei, sParam: String; iShowCmd: Integer = sw_Shownormal): Integer;
type
  TWow64DisableWow64FsRedirection = function(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  TWow64EnableWow64FsRedirection = function(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
var
  Wow64FsEnableRedirection: LongBool;

Function IsWin64: Boolean;
begin
  With TRegistry.Create do begin
   RootKey := HKEY_LOCAL_MACHINE;
   Result := KeyExists('\SOFTWARE\Wow6432Node');
   Free;
  end;
end;

var
  hHandle: THandle; // Handle zur DLL
  Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection;
  Wow64EnableWow64FsRedirection: TWow64EnableWow64FsRedirection;
begin

if isWin64 then begin // Win64

 hHandle := LoadLibrary(PChar('kernel32.dll'));
  if hHandle <> 0 then begin
    @Wow64EnableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64EnableWow64FsRedirection');
    @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64DisableWow64FsRedirection');

    if (@Wow64EnableWow64FsRedirection <> nil) AND (@Wow64DisableWow64FsRedirection <> nil) then begin // Alles OK? Dann Datei ausführen!
      Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection);
      Result := ShellExecute(0, nil, PChar(sdatei), Pchar(sParam), nil, iShowCmd);
      Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);
    end;

    FreeLibrary(hHandle);
  end;

end else begin // Normales Win32
 Result := ShellExecute(0, nil, PChar(sdatei), Pchar(sParam), nil, iShowCmd);
end;


end;
Der Aufruf erfolgt dann über:

 Fileexec('C:\Windows\regedit.exe', ''); Vielleicht kann's ja jemand anders nochmals testen und ggf. Optimierungsmöglichkeiten posten.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.067 Beiträge
 
Delphi 12 Athens
 
#9

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 13:53
Da kernel32.dll in deinen Anwendungen eh immer bereits geladen sein wird, brauchst du ssie nicht nochmals zu laden/freizugeben ^^

FreeLibrary(hHandle); entfällt und hHandle := LoadLibrary('kernel32.dll'); wird durch hHandle := GetModuleHandle('kernel32.dll'); ersetzt.

Dein IsWin64 kannst du eigentlich auch weglassen, denn du fühst die Anwendung ja so oder so aus, selbst wenn Wow64DisableWow64FsRedirection nicht funkioniert.
Außerdem wird Wow64DisableWow64FsRedirection eh nur unter Win64 laufen.
Also kann man auch durch Aufrufen 'ner Win64-Funktion gleich mit auf Win64 testen.

Hier mal eine Kurzfassung deines Codes, wobei hier bei einem fehlgeschalgenem Aufruf mit Wow64FsRedirection nochmal es nochmals ohne versucht wird.
Delphi-Quellcode:
Function FileExec(Const sDatei, sParam: String; iShowCmd: Integer = sw_ShowNormal): Integer;
  Type TWow64DisableWow64FsRedirection = Function(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
    TWow64EnableWow64FsRedirection = Function(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;

  Var hHandle: THandle;
    Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection;
    Wow64EnableWow64FsRedirection: TWow64EnableWow64FsRedirection;
    Wow64FsEnableRedirection: LongBool;

  Begin
    hHandle := GetModuleHandle('kernel32.dll');
    @Wow64EnableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64EnableWow64FsRedirection');
    @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64DisableWow64FsRedirection');
    If (hHandle <> 0) and (@Wow64EnableWow64FsRedirection <> nil)
      and (@Wow64DisableWow64FsRedirection <> nil) Then
      Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection);
      Result := ShellExecute(0, nil, PChar(sDatei), PChar(sParam), nil, iShowCmd);
      Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);
    End Else Result := 0;
    Result := Result or ShellExecute(0, nil, PChar(sDatei), PChar(sParam), nil, iShowCmd);
  End;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Rakshasa
Rakshasa

Registriert seit: 1. Nov 2003
182 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Datei ausführen unter Windows 64-Bit

  Alt 20. Feb 2007, 14:20
Zitat von himitsu:
Da kernel32.dll in deinen Anwendungen eh immer bereits geladen sein wird, brauchst du ssie nicht nochmals zu laden/freizugeben ^^
FreeLibrary(hHandle); entfällt und hHandle := LoadLibrary('kernel32.dll'); wird durch hHandle := GetModuleHandle('kernel32.dll'); ersetzt.

Dein IsWin64 kannst du eigentlich auch weglassen, denn du fühst die Anwendung ja so oder so aus, selbst wenn Wow64DisableWow64FsRedirection nicht funkioniert.
Außerdem wird Wow64DisableWow64FsRedirection eh nur unter Win64 laufen.
Also kann man auch durch Aufrufen 'ner Win64-Funktion gleich mit auf Win64 testen.
Hallo himitsu,

danke mal wieder für Deine Optimierung des Codes. Funktioniert jetzt unter Win64 (Vista) und Win32 (XP, SP2) fast ohne Probleme oder Fehler.
Einziges Problem habe ich mit der TTaskDialog Komponente von TMS. Sobald eine Datei über FileExec() aufgerufen wurde, kann der Dialog nicht mehr angezeigt werden (keine Fehlermeldungen o.ä.).
ShowMessage(), MessageDlg() funktionieren normal ...
Dieser Fehler taucht übrigens nicht auf, wenn ich die Datei direkt über Shellexecute() (also ohne Wow64DisableWow64FsRedirection) ausführe.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz