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 Windows 7 64Bit Redirection (https://www.delphipraxis.net/155861-windows-7-64bit-redirection.html)

amigage 10. Nov 2010 16:26

Windows 7 64Bit Redirection
 
Hallo liebe Gemeinde,

ich versuche mit einem 32 Bit Programm unter 64 Bit ein Systemprogramm aufzurufen, z.B. die Bildschirmtastatur.

Ich habe mich in die Problematik der 64Bit Redirection hier im Forum eingelesen und einige gute Ansätze gefunden. Leider funktionieren die bei mir nicht?

Debuggen kann ich leider nur über Meldungen, da mein Delphi 2009 nicht auf dem 64Bit System installiert ist.

Delphi-Quellcode:
procedure TFormDlg.BitBtn1Click(Sender: TObject);
var
  is64Bit : boolean;
begin
  is64Bit := Is64BitViaRegistry;
  showmessage('is64Bit : ' + BoolToStr(is64Bit));
  if (is64Bit = true) then
    ChangeFSRedirection(true); // Redirect stoppen
  showmessage ('start von osk.exe');
  ShellExecute(handle, 'open', PChar('%WinDir%\system32\') + 'osk.exe'), NIL, NIL, SW_SHOW);
  if (is64Bit = true) then
    ChangeFSRedirection(false); // Redirect wieder starten
end;
Die Funktion ChangeFSRedirection() habe ich hier aus dem Forum und nur um die Meldungen erweitert.

Delphi-Quellcode:
function ChangeFSRedirection(bDisable: Boolean): Boolean;
type
     TWow64DisableWow64FsRedirection = Function(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
     TWow64EnableWow64FsRedirection = Function(var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
var
    hHandle: THandle;
    Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection;
    Wow64EnableWow64FsRedirection: TWow64EnableWow64FsRedirection;
    Wow64FsEnableRedirection: LongBool;
begin
  Result := false;

  try
    hHandle := GetModuleHandle('kernel32.dll');
    @Wow64EnableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64EnableWow64FsRedirection');
    @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle, 'Wow64DisableWow64FsRedirection');

    if bDisable then
    begin
     if (hHandle <> 0) and (@Wow64DisableWow64FsRedirection <> nil) then
     begin
       showmessage('Abschaltung starten');
       Result := Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection);
       showmessage('disabled : ' + BoolToStr(Result));
     end;
    end else
    begin
     if (hHandle <> 0) and (@Wow64EnableWow64FsRedirection <> nil) then
     begin
       showmessage('Abschaltung wieder einschalten');
       Result := Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);
       showmessage('enabled : ' + BoolToStr(Result));
       Result := True;
     end;
    end;
  Except
  end;
end;
Statt
  1. is64Bit : true
  2. Abschaltung starten
  3. disabled : true
  4. start von osk.exe
  5. Abschaltung wieder einschalten
  6. enabled : true

wird mir folgende, unlogische Abfolge unter 64Bit angezeigt:
  1. is64Bit : true
  2. Abschaltung starten
  3. enabled : true

Kann mir jemand bei der Fehlersuche behilflich sein? Liegt es am Delphi 2009?

Vielen Dank im Voraus.
Amigage

jfheins 10. Nov 2010 16:53

AW: Windows 7 64Bit Redirection
 
Versuch mal, ob es vielleicht mit einem verändertem Pfad klappt:
Zitat:

%windir%\Sysnative\osk.exe
http://msdn.microsoft.com/en-us/libr...87(VS.85).aspx

Assarbad 10. Nov 2010 17:46

AW: Windows 7 64Bit Redirection
 
Moin,

also erstmal solltest du nicht die alten Funktionen verwenden, sondern die neuen: MSDN-Library durchsuchenWow64RevertWow64FsRedirection und MSDN-Library durchsuchenWow64DisableWow64FsRedirection.

Zitat:

Wow64EnableWow64FsRedirection Function

Enables or disables file system redirection for the calling thread.

This function may not work reliably when there are nested calls. Therefore, this function has been replaced by the MSDN-Library durchsuchenWow64DisableWow64FsRedirection and MSDN-Library durchsuchenWow64RevertWow64FsRedirection functions.
Und wenn du ein kleines Beispielprojekt anhängst, kann ich oder jemand anderes auch gern mal live auf einem x64 testen ;)

Zitat:

Zitat von jfheins (Beitrag 1060809)

Nur um es hervorzuheben, denn es muß ja nicht zwangsläufig spezifisch Windows 7 sein, auch wenn's im Thementitel steht:

Zitat:

Windows Server 2003 and Windows XP: The Sysnative alias was added starting with Windows Vista.

shmia 10. Nov 2010 19:18

AW: Windows 7 64Bit Redirection
 
Zitat:

wird mir folgende, unlogische Abfolge unter 64Bit angezeigt:
1.is64Bit : true
2.Abschaltung starten
6.enabled : true
Sieht für mich logisch aus - mit der Abschaltung von 32Bit FS werden wohl auch Bildschirmausgaben mit ShowMessage gestört.
Deshalb fehlen dann die Punkte 3. bis 5.

amigage 11. Nov 2010 17:51

AW: Windows 7 64Bit Redirection
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Assarbad:
Besten Dank für den Hinweis, bezüglich Wow64RevertWow64FsRedirection, jedoch besteht ja bei mir das Problem bereits bei Wow64DisableWow64FsRedirection, denn da scheint ja schon irgendwie etwas schief zu laufen. Ich habe trotzdem mal eine Änderung vorgenommen. The same procedure. :cry:

Ich habe mal ein Beispielprojekt angelegt. Eine kompilierte Exe ist auch beigelegt. Würde mich freuen, wenn ihr das mal testen und über den Quellcode schauen könntet (speziell die Funktion ChangeFSRedirection() ).

@shmia:
Für mich ist die Schlussfolgerung nicht ganz nachzuvollziehen, denn dann hätte ja zumindest die Bildschirmtastatur starten müssen, oder?

Ich danke Euch im Voraus für jede Hilfe und jeden Hinweis.

Assarbad 11. Nov 2010 18:22

AW: Windows 7 64Bit Redirection
 
Du benutzt es aber so wie du es schriebst, oder? Also nicht innerhalb verschiedener Threads oder ähnliches?

amigage 11. Nov 2010 19:08

AW: Windows 7 64Bit Redirection
 
Nein, ganz normal bei Klick auf eine Schaltfläche. Keine Threads!

Assarbad 11. Nov 2010 19:15

AW: Windows 7 64Bit Redirection
 
Zitat:

Zitat von amigage (Beitrag 1061040)
Nein, ganz normal bei Klick auf eine Schaltfläche. Keine Threads!

Okay, gucke nachher mal drüber.

Bummi 11. Nov 2010 19:50

AW: Windows 7 64Bit Redirection
 
Ich denke shima hat recht
nimm statt showmessage mal Memo1.lines.add

is64Bit : true
Abschaltung starten
disabled : true
start von osk.exe
Abschaltung wieder einschalten
enabled : true

OSK öffnet sich

Assarbad 11. Nov 2010 20:03

AW: Windows 7 64Bit Redirection
 
Zitat:

Zitat von Bummi (Beitrag 1061056)
Ich denke shima hat recht
nimm statt showmessage mal Memo1.lines.add

is64Bit : true
Abschaltung starten
disabled : true
start von osk.exe
Abschaltung wieder einschalten
enabled : true

OSK öffnet sich

Schließe mich an. Getestet auf Win 7 x64.

Assarbad 11. Nov 2010 20:23

AW: Windows 7 64Bit Redirection
 
Kleiner Nachtrag.

Du solltest meines Erachtens nach nicht extra testen ob du auf x64 läufst und vor allem nicht via Registry sondern via MSDN-Library durchsuchenGetNativeSystemInfo. Wie gesagt, testen ist aber m.E.n. unnötig, weil auf einem 32bit-System die Funktionen nicht von kernel32.dll exportiert werden ;)

Dezipaitor 12. Nov 2010 09:52

AW: Windows 7 64Bit Redirection
 
Also dieser Code startet bei mir osk 64bit. Ohne Wow64DisableWow64FsRedirection wollte osk garnicht erst starten. Die 32Bit funkz wohl nicht unter 64bit (oder will nicht).

Delphi-Quellcode:
uses
  JwaWindows,
  SysUtils;

function GetNativeWindowsDirectory : String;
var
  P : array[0..MAX_PATH] of Char;
begin
  SHGetFolderPath(0, CSIDL_SYSTEM, 0, SHGFP_TYPE_DEFAULT, @P);

  result := P;
end;

var
  oldValue : Pointer;
  Path : String;
begin
  Path := GetNativeWindowsDirectory + '\osk.exe';

  if not Wow64DisableWow64FsRedirection(oldValue) then
    RaiseLastOSError;

  ShellExecuteW(0, 'open', PChar(Path), '', '', SW_SHOWNORMAL);

  Wow64RevertWow64FsRedirection(oldValue);
end.
ShowMessage funktioniert nur dann, wenn es mindestens einmal vor Wow64DisableWow64FsRedirection aufgerufen wurde. Sonst sind nicht alle DLLs geladen und es wird versucht eine 64bit DLL in einen 32bit Prozess zu laden. Zumindest ich bekomme eine generische Exception C0FB007E, was wohl vom Delphi delay loader Mechanismus stammt. $7E = 126d ist übrigens der Win32 Code für Modul nicht gefunden.

amigage 13. Nov 2010 15:55

AW: Windows 7 64Bit Redirection
 
Ich danke Euch für die rege Teilnahme an meinem Problem :roll:

Leider wird das irgendwie nichts bei mir. Showmessage habe ich durch Memo.Lines.Add ersetzt und jetzt werden auch die Ausgaben gemacht.
  1. is64Bit : true
  2. Abschaltung starten
  3. disabled : true
  4. start von C:\Windows\system32\osk.exe
  5. isStarted : 5 // Rückgabe von Shellexecute
  6. Abschaltung wieder einschalten
  7. enabled : true


Aber osk.exe startet immer noch nicht. Also habe ich mir den Rückgabewert von Shellexecute ausgeben lassen. Der sollte über 32 sein, aber es wird eine 5 ausgegeben. Und die besagt "Der Zugriff wurde auf die angegebene Datei verweigert." Ich weiß nicht warum... Kann mir das jemand erklären?

Danke.

Bummi 13. Nov 2010 18:11

AW: Windows 7 64Bit Redirection
 
auch wenn Du die Anwendung als Administrator startest?

Assarbad 13. Nov 2010 18:19

AW: Windows 7 64Bit Redirection
 
Zusammen mit Thomas' Vorschlag würde ich noch vorschlagen, daß du Process Monitor von (Sysinternals/MS Technet) mal ne Chance gibst. Wenn du dann so filterst, daß nur dein Programm und osk.exe angezeigt werden und es auf Dateiaktionen beschränkst, kannste den gefilterten Dump (PML!) hier mal anhängen und dann können wir alle miträtseln ;)

amigage 14. Nov 2010 09:02

AW: Windows 7 64Bit Redirection
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich habe einmal das Log vom Process Monitor angehangen. Ich hoffe, ihr könnt erkennen, wo das Problem ist. Das 64 Bit System ist übrigens in Englisch, was aber nicht das Problem sein sollte, oder?

@Bummi:
Dasselbe passiert auch, wenn ich das Programm als Admin ausführe.

Ich wünsche Euch allen einen schönen Sonntag.

Dezipaitor 14. Nov 2010 11:05

AW: Windows 7 64Bit Redirection
 
Hast du mal meinen Code ausprobiert oder machst du eine neue EXE zum testen, weil die alte Exe funktioniert bei mir nicht.

Assarbad 14. Nov 2010 14:57

AW: Windows 7 64Bit Redirection
 
Zitat:

Zitat von amigage (Beitrag 1061378)
So, ich habe einmal das Log vom Process Monitor angehangen. Ich hoffe, ihr könnt erkennen, wo das Problem ist.

Ich sehe ehrlich gesagt kein Problem. Laut dem Report sieht es so aus als ob osk.exe (und zwar die x64-Variante, denn es gibt ja zwei auf dem Win7 x64) erfolgreich gestartet wird und dann auch gleich wieder beendet wird. Wenn du also einen Fehler bekommst, sollte der innerhalb von osk.exe passieren ...

Zitat:

Zitat von amigage (Beitrag 1061378)
Das 64 Bit System ist übrigens in Englisch, was aber nicht das Problem sein sollte, oder?

Nein.

Zitat:

Zitat von amigage (Beitrag 1061378)
Ich wünsche Euch allen einen schönen Sonntag.

Dir auch.

Dezipaitor 14. Nov 2010 20:16

AW: Windows 7 64Bit Redirection
 
Wie gesagt, sein Code funktioniert bei mir nicht, meiner jedoch schon.
Vielleicht mal testen?
Solange das nicht geschehen ist, werde ich auch nicht mehr weiter raten.

Assarbad 14. Nov 2010 20:18

AW: Windows 7 64Bit Redirection
 
Zitat:

Zitat von Dezipaitor (Beitrag 1061491)
Wie gesagt, sein Code funktioniert bei mir nicht, meiner jedoch schon.

Ich hatte alle ShowMessage-Aufrufe auskommentiert. Dann ging auch sein Code.

amigage 15. Nov 2010 07:35

AW: Windows 7 64Bit Redirection
 
@Dezipaitor:
Könntest Du mir mal Deine exe hier anbieten? Ich arbeitet derzeit ohne die Jedi-Komponenten und würde sicher gehen wollen, dass diese funktionieren, bevor ich sie mir installiere.

Ich habe bei den Jedi Komponenten sowieso keinen Überblick, welche ich da wann benötige. Aber das ist ein anderes Thema :-D

Dezipaitor 15. Nov 2010 09:45

AW: Windows 7 64Bit Redirection
 
Die JEDI API muss nicht installiert werden. Einfach die Pfade inkludieren.

Und hier gibt es eine Übersicht:
http://wiki.delphi-jedi.org/index.php?title=Main_Page

gore 15. Nov 2010 11:47

AW: Windows 7 64Bit Redirection
 
64Bit Redirection? Wieso immer gleich mit Kanonen auf Spatzen schießen? Die erste Antwort von jfheins ist Microsoft konform.

Zitat:

32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.

Solange man mit Delphi keine 64bit Programme erzeugen kann, reicht folgendes:
Delphi-Quellcode:
  if IsProcess32OnWin64(GetCurrentProcess) then Exe:='%WinDir%\Sysnative\osk.exe' else Exe:='%WinDir%\system32\osk.exe';


IsProcess32OnWin64 ist gleichbedeutend mit Deiner Is64BitViaRegistry (und ist auch Microsoft konform).
Delphi-Quellcode:
function IsProcess32OnWin64(ProcessHandle:THandle):boolean;
type
  TIsWow64Process = function(Handle: THandle; var Res: BOOL): BOOL; stdcall; // Type of IsWow64Process API fn
var
  IsWow64Result: BOOL;     // Result from IsWow64Process
  IsWow64Process: TIsWow64Process; // IsWow64Process fn reference
begin
  result:=false;
  IsWow64Process := GetProcAddress( GetModuleHandle('kernel32.dll'), 'IsWow64Process' );
  if Assigned(IsWow64Process) then begin
    if IsWow64Process(ProcessHandle,IsWow64Result) AND IsWow64Result then result:=true;  
  end;                                                                                   // google: Running 32-bit Applications (Windows)
end;                                                                                    

function IsProcess64bit(ProcessHandle:THandle):boolean;
begin
  result:= IsWin64bit AND not IsProcess32OnWin64(ProcessHandle);
end;

amigage 15. Nov 2010 18:41

AW: Windows 7 64Bit Redirection
 
Liste der Anhänge anzeigen (Anzahl: 1)
@gore
Danke für den Hinweis, aber wenn ich das mit Sysnative umsetze, erhalte ich von Shellexecute() die Rückmeldung 3 (Datei nicht gefunden). Also rufe ich generell '%WinDir%\system32\osk.exe' auf.

@all
Aber - und jetzt wird es verrückt - ich habe eine nachvollziehbare, aber nicht praktikable Lösung gefunden.

Ich habe zwei Schaltflächen:
1. Schaltfläche ist Version 1 mit ChangeFSRedirection()
2. Schaltfläche ist Version 2 mit IsProcess32OnWin64 von gore
  • Klick auf Schaltfläche 2 -> Shellexecute = 5; Windows meldet: Could not start On-Screen Keyboard.
  • Klick auf Schaltfläche 1 -> Shellexecute = 42; Und plötzlich startet die Bildschirmtastatur :shock:
  • bei jedem weiteren Klick auf Schaltfläche 1 oder 2 startet die BST wieder mit 42

Danach schließe ich das kleine Testprogramm:
  • Ich starte mit Klick auf Schaltfläche 1 -> Shellexecute = 5; nichts passiert (so wie bisher)
  • Klick auf Schaltfläche 2 -> Shellexecute = 5; nichts passiert (so wie bisher)
  • bei jedem weiteren Klick auf Schaltfläche 1 oder 2 passiert nichts

Ich kann mir das Verhalten nicht erklären. Also habe ich versucht, eine Mischung von beidem zu erstellen, aber dann habe ich wieder Shellexecute() mit Rückgabe von 5.

Delphi-Quellcode:
  IsProcess32OnWin64(GetCurrentProcess); // von gore

  ChangeFSRedirection(true); // Redirect stoppen
  Path := CreateCorrectWinDir('%WinDir%\system32\osk.exe');
  Memo1.Lines.Add('start von ' + Path);
  isStarted := ShellExecute(0, 'open', PChar(Path), '', '', SW_SHOWNORMAL);
  Memo1.Lines.Add('isStarted : ' + IntToStr(isStarted));
  ChangeFSRedirection(false); // Redirect wieder starten
Ich bin echt am Verzweifeln. Langsam muss ich davon ausgehen, dass an meinen frisch installierten, englischen Windows 7 64 Bit irgendetwas nicht funktioniert.

Könntet Ihr daher bitte noch einmal mein Testprogramm (bereits kompiliert) probieren und mir Eure Ergebnisse unter Eurem Windows 7 64Bit durchgeben?

Dezipaitor 15. Nov 2010 18:59

AW: Windows 7 64Bit Redirection
 
Liste der Anhänge anzeigen (Anzahl: 1)
Probier mal die angehängte Version

Assarbad 15. Nov 2010 19:59

AW: Windows 7 64Bit Redirection
 
Zitat:

Zitat von gore (Beitrag 1061591)
Solange man mit Delphi keine 64bit Programme erzeugen kann, reicht folgendes:
Delphi-Quellcode:
  if IsProcess32OnWin64(GetCurrentProcess) then Exe:='%WinDir%\Sysnative\osk.exe' else Exe:='%WinDir%\system32\osk.exe';

Auch bis zum Ende gelesen zum Thema SysNative? :zwinker:

Zitat:

Zitat von gore (Beitrag 1061591)
IsProcess32OnWin64 ist gleichbedeutend mit Deiner Is64BitViaRegistry (und ist auch Microsoft konform).

Leider nein. Ich habe auch auf 32bit-Systemen schon die Wow...Node gesehen. Da setzt man sich in die Nesseln. Lieber die Methode mit MSDN-Library durchsuchenIsWow64Process (wie in deinem Beitrag) oder MSDN-Library durchsuchenGetNativeSystemInfo (s.o.).

Dezipaitor 16. Nov 2010 00:40

AW: Windows 7 64Bit Redirection
 
Vergiß alles, ich hab mich gerade damit etwas beschäftigt.
Unter XE kann man Osk.exe einfach ausführen. Im 64bit Explorer geht es nicht.

Hier wird geraten, dass .NET mit abgeschalteten Redirection nicht funktioniert. Das Shell zeugs mit ShellExecute geht alles außerdem über COM, denn ich bekomme, wenn ich
Delphi-Quellcode:
CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
verwende, eine Prozedur wurde (im Modul) nicht gefunden. D.h. das alles ist in Windows ganz tief drin, denn osk.exe ist ja auch in der WhiteList für AutoElevation.
Delphi scheint da irgendetwas mit .NET inuts zu haben, damit es funktioniert.

amigage 16. Nov 2010 10:15

AW: Windows 7 64Bit Redirection
 
Also wieder Start bei 0 :pale:

Könntet Ihr bitte einmal meine osk.zip ausprobieren, ob ihr den o.g. Ablauf auch bei Euch bestätigen könnt.

Danke.

Dezipaitor 16. Nov 2010 16:42

AW: Windows 7 64Bit Redirection
 
Mit FreePascal eine kleine 64bit App bauen, die das für dich macht. Vielleicht gehts so.

Dezipaitor 29. Nov 2010 17:37

AW: Windows 7 64Bit Redirection
 
Wie man das 64Bit OnScreenKeyboard starten kann.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:44 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