pedant
Goto Top

Exe-Dateien in System32 vorhanden oder nicht?

Hallo,

ich stieß auf eine Merkwürdigkeit, die ich mir nicht erklären kann.
Es geht um die Anwesenheit von Exe-Dateien in Windows (7x64Pro).

Liste ich in einer Eingabeaufforderung alle Exes aus System32 auf
dir C:\Windows\System32\*.exe
so erhalte ich diverse Treffer.

Mach ich das Gleiche aus c# heraus
string[] dateiliste = System.IO.Directory.GetFiles("C:\\Windows\\System32", "*.exe", SearchOption.TopDirectoryOnly);
foreach (string dateiname in dateiliste) {ausgabetextbox.Text += dateiname + "\r\n";};

so erhalte ich ebenfalls diverse Treffer.

Die Listen von dir und von c# sind aber merkwürdigerweise nicht deckungsgleich.
Einige Dateien sind nur in der einen oder der anderen Auflistung vorhanden, wobei die Schnittmenge recht groß ist, aber keine der beiden Listen ist eine wahr Untermenge der Anderen.

Als Beispiel nehme ich die tskill.exe.
Laut dir ist sie vorhanden aber laut c# nicht.
Konsequenterweise wirkt sich das auch auf die Nutzbarkeit aus.

Aus einer Eingabeaufforderung heraus ist diese Exe benutzbar:
C:\Windows\System32\tskill.exe notepad /a
(Notepad wird abgeschossen.)

Führe ich denselben Befehl mit c# aus:
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\tskill.exe";
p.StartInfo.Arguments = "notepad /a";
p.Start();

So erhalte ich eine Exception: Das System kann die angegebene Datei nicht finden
Mit einem OpenFileDialog in c# ist tskill.exe auch nicht in System32 auffindbar.

Bei C:\Windows\System32\explorer.exe ist es übrigens genau umgekehrt.

Es gibt auch noch den Ordner
C:\Windows\SysWOW64 aber in dem ist tskill.exe auf beide Arten nicht zu finden.
tskill.exe habe ich dann noch in diesem Ordner gefunden:
C:\Windows\winsxs\amd64_microsoft-windows-t..es-commandlinetools_31bf3856ad364e35_6.1.7600.16385_none_40a54b0d12b542e8
und dort ist es von cmd und c# auffind- und ausführbar.
Ich würde aber echte Dateien (keine Verknüpfungen, Aliase oder sonstig "Virtuelles") eher in System32 erwarten, als in winsxs.

Was hat sich Microsoft dabei gedacht?
Okay, die Frage ziehe ich zurück.
Letztendlich geht es mir nur darum, wie und womit ich einer Datei ansehen kann, ob sie wirklich vorhanden ist?

Gruß Frank

Content-Key: 273873

Url: https://administrator.de/contentid/273873

Ausgedruckt am: 03.10.2022 um 01:10 Uhr

Mitglied: 114757
Lösung 114757 05.06.2015 aktualisiert um 16:36:13 Uhr
Goto Top
Mitglied: emeriks
Lösung emeriks 05.06.2015 aktualisiert um 16:36:15 Uhr
Goto Top
Hi,
ich nehme an, das hat was mit der Datei- und Registrierungsvirtualisierung zu tun.

File System Redirector

E.
Mitglied: Pedant
Pedant 05.06.2015 um 16:36:05 Uhr
Goto Top
Hallo jodel32, Hallo emeriks,

ja, genau das ist es und ich bin zweimal darauf reingefallen.

Meine c#-Exe ist nur 32-Bit und meine cmd.exe (in der Eingabeeaufforderung) 64-Bit.

C:\Windows\System32\cmd.exe /k C:\Windows\System32\tskill.exe notepad /a
Das findet und startet die tskill.exe in System32

1. 32Bit-Falle
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\tskill.exe";
p.StartInfo.Arguments = "notepad /a";
p.Start();

Das sucht tskill.exe erfolglos in SysWOW64

2. 32Bit-Falle
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
p.StartInfo.Arguments = "/k C:\\Windows\\System32\\tskill.exe notepad /a";
p.Start();

Hier hatte ich gedacht, ich wäre schlauer und führe cmd.exe statt tskill.exe aus und dacht, dass müsse ja jetzt dasselbe wie in der Eingabeaufforderung sein.

Mein 32-Programm hat aber nicht die angegebene System32\\cmd.exe ausgeführt, sondern die 32-Bit-Variante SysWOW64\\cmd.exe und die hat ihrerseits auch nur wieder tskill.exe in SysWOW64 nicht gefunden.

Hier könnte sich noch die Frage anschließen, ob und wie man mit c#-32-Bit die 64-Bit-cmd.exe als externen Prozess starten kann, aber das wäre ein anderes Thema.
Ich betracht meine Frage als erledigt.

Gruß und Dank
Frank
Mitglied: rubberman
Lösung rubberman 06.06.2015 aktualisiert um 17:04:22 Uhr
Goto Top
Hallo Frank.

ob und wie man mit c#-32-Bit die 64-Bit-cmd.exe als externen Prozess starten kann
@emeriks hat dir genau den richtigen Link geliefert und auch bei @114757 gibt es im verlinkten Beitrag auf SamLogic unten den richtigen Hinweis. Wenn du im WOW64 Modus auf das Dateisystem im system32 Verzeichnis zugreifen willst, musst du auf das virtuelle Verzeichnis "%systemroot%\sysnative" zurückgreifen.

Grüße
rubberman
Mitglied: Pedant
Pedant 06.06.2015 um 17:04:09 Uhr
Goto Top
Hallo rubberman,

danke für den Hinweis.
Die Links hatte ich nur soweit gelesen, bis klar war was der Unterschied zwischen System32 und SysWOW64 ist.
Ich habe es jetzt mit sysnative ausprobiert und es funktioniert prima.

tskill.exe lässt sich so direkt ausführen
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\sysnative\\tskill.exe";
p.StartInfo.Arguments = "notepad /a";
p.Start();


Man kann es auch als Parameter für die cmd.exe verwenden
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\sysnative\\cmd.exe";
p.StartInfo.Arguments = "/k C:\\Windows\\System32\\tskill.exe notepad /a";
p.Start();


Man darf es nur nicht übertreiben...
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\sysnative\\cmd.exe";
p.StartInfo.Arguments = "/k C:\\Windows\\sysnative\\tskill.exe notepad /a";
p.Start();

Das funktioniert nicht, Ausgabe: Das System kann den angegebenen Pfad nicht finden.

Gruß Frank
Mitglied: emeriks
emeriks 06.06.2015 um 17:11:20 Uhr
Goto Top
Ein einfaches, vorhergehendes Prüfen mit
sollte es reißen ...

System.IO.File.Exists

E.
Mitglied: rubberman
rubberman 06.06.2015 aktualisiert um 19:08:07 Uhr
Goto Top
Hallo Frank.

Man darf es nur nicht übertreiben
Naja, du startest die 64Bit Version der cmd.exe. Die läuft dann also nicht im WOW64 Modus. Somit existiert das sysnative Verzeichnis für diesen Prozess nicht.
Wenn man das Prinzip einmal durchschaut hat, ist es ganz einfach ... face-wink


OK, noch mal in aller Kürze:

  • Ein Prozess läuft (nur) dann im WOW64 Modus, wenn er ein 32-Bit Prozess auf einem 64-Bit Windowssystem ist.
  • Läuft ein Prozess im WOW64 Modus, dann werden Pfade, die auf System32 (oder Unterverzeichnisse) zeigen, automatisch in das SysWOW64 Verzeichnis (oder Unterverzeichnisse) umgeleitet, was in der Regel Sinn macht.
  • Will man aus einem WOW64 Prozess auf das reale System32 Verzeichnis im Dateisystem zugreifen, muss man auf das virtuelle Sysnative Verzeichnis zurückgreifen.
  • Nur WOW64 Prozesse können auf das Sysnative Verzeichnis zugreifen. Für 64-Bit Prozesse auf einem 64-Bit Windowssystem (oder auch 32-Bit Prozesse auf einem 32-Bit Windowssystem) gibt es die Dateisystem-Umleitung nicht und System32 zeigt auf das reale System32 Verzeichnis im Dateisystem.
  • Zur Prüfung, ob ein Prozess im WOW64 Modus läuft, kannst du die Existenz des virtuellen Sysnative Verzeichnisses prüfen oder man nutzt die extra zu diesem Zweck entwickelte IsWow64Process WinAPI Funktion der kernel32.dll.

Grüße
rubberman
Mitglied: Pedant
Pedant 06.06.2015 um 20:39:47 Uhr
Goto Top
Hallo rubberman,
Man darf es nur nicht übertreiben
das war eher scherzhaft gemeint.
Den zugehörigen Code hatte ich gepostet um aufzuzeigen, dass sysnative nicht als pauschaler Ersatz für System32 verwendet werden kann.
Trotzdem danke für Deine Ausführungen, die den Sachverhalt sicher eindeutiger erklären, als mein Fehler-Beispiel.
Wenn man das Prinzip einmal durchschaut hat...
Das sollte spätestens jetzt der Fall sein.

Gruß und Dank
Frank