
Meine Anwendung schreibt Protokolle in ein Verzeichnis, das fest als „Logs“ codiert ist und sich im Laufzeitverzeichnis meiner Anwendung befindet.
Heute hat mich ein Kunde gefragt, ob es möglich sei, diese Protokolle an einem anderen Ort (auf einem anderen Computer) zu speichern.
Als ersten Test habe ich versucht, einen symbolischen Link zu erstellen:
- Ich habe die Anwendung abgebrochen.
- Ich habe das Verzeichnis "Logs" entfernt.
- Mithilfe eines WSL auf meinem Computer habe ich einen symbolischen Link erstellt, etwa so
ln -s /mnt/c/Temp_Folder/TestLog/ /mnt/c/<Application>/Logs
: - Ich habe meine Anwendung gestartet.
Ich habe keine Protokolle im Verzeichnis gesehen C:\Temp_Folder\TestLog\
.
Ich sehe verschiedene Gründe:
- Entweder ist es eine völlig dumme Idee, zu versuchen, Linux-Technologie auf einem Windows-Computer zu verwenden.
- Beides könnte funktionieren, allerdings müssen dabei einige zusätzliche Dinge berücksichtigt werden.
Ich hoffe, es ist die zweite Wahl, aber was muss ich in diesem Fall berücksichtigen?
Bearbeiten nachHarry's Antwort:
Warum WSLs verwenden ln -s
, wenn Sie beispielsweise Windows-Technologie verwenden können mklink
? :-)
Mir gefällt die Idee, aber leider scheint sie nicht zu funktionieren, wie man an den folgenden Experimenten sehen kann:
C:\<Runtime_Dir>mklink /D Logs E:\TestLog\
=> result:
29/03/2024 08:21 <SYMLINKD> Logs [E:\TestLog\]
=> Der symbolische Verzeichnislink wird also tatsächlich Logs
erstellt, aber wenn ich meine Anwendung starte, scheint sie keine Protokolle mehr zu schreiben (ich sehe in einem Konsolenfenster, dass sie erstellt werden, aber sie werden nicht in einer Datei niedergeschrieben).
Einige andere Experimente: (Ich erinnere mich an etwas über eine Kreuzung von früher, aber die Einzelheiten sind mir entfallen)
C:\<Runtime_Dir>mklink /D /J Logs E:\TestLog\
Local volumes are required to complete the operation.
C:\<Runtime_Dir>mklink /D /H Logs E:\TestLog\
The system cannot find the path specified.
C:\<Runtime_Dir>mklink /J Logs E:\TestLog\
Local volumes are required to complete the operation.
Edit2 nach einigen weiteren Experimenten:
Es scheint nicht zu funktionieren, wenn ich auf ein anderes Laufwerk verweise, aber es scheint zu funktionieren, wenn ich auf ein anderes Verzeichnis auf demselben Computer verweise, wie Sie hier sehen können:
C:\<Runtime_Dir>mklink /D Logs C:\Temp_Folder\TestLog\
symbolic link created for Logs <<===>> C:\Temp_Folder\TestLog\
C:\<Runtime_Dir>mklink /D /J Logs C:\Temp_Folder\TestLog\
Junction created for Logs <<===>> C:\Temp_Folder\TestLog\
Ich kann bestätigen, dass in beiden Fällen die Protokolle erstellt werden!
Mit anderen Worten, das Problem besteht nicht darin, dass der symbolische Link/die Verbindung unter Windows nicht funktioniert, sondern darin, dass der symbolische Link/die Verbindung auf ein anderes Laufwerk verweist.
Ich erinnere mich, dass es zwei, sogar drei Möglichkeiten gibt, in Windows ein Laufwerk zu erstellen (eine Laufwerkszuordnung, ein Subst (?) und noch eins (???), das ist alles sehr verschwommen in meinem Kopf), und ich frage mich, ob die Geschichte mit dem symbolischen Link/der Verbindung bei einer Art von Laufwerk funktioniert, bei der anderen aber nicht, und ob es eine Möglichkeit gibt, dies zu umgehen.
Edit3 nach der Antwort vonu1686_Schwerkraft:
Selbst wenn der UNC-Pfad verwendet wird und das „richtige“ Verhalten konfiguriert ist, scheint es trotzdem nicht zu funktionieren:
fsutil behavior query symlinkEvaluation
Local to local symbolic links are enabled.
Local to remote symbolic links are enabled. => That's the one, isn't it?
Remote to local symbolic links are disabled.
Remote to remote symbolic links are disabled.
C:\<Runtime_Dir>mklink /D Logs \\petrvs01\Log\TestLog\
symbolic link created for Logs <<===>> \\petrvs01\Log\TestLog\
Der Link wird zwar erstellt, es werden dort jedoch keine Logfiles erstellt.
Da ich glaube, hier auf der richtigen Spur zu sein, habe ich mich entschlossen, einen weiteren Test durchzuführen: Ich gehe mit dem Windows-Explorer in das Logs
Verzeichnis/den symbolischen Link/die Verknüpfung und erstelle über das Kontextmenü des Explorers eine einfache Textdatei. Dies funktioniert jedoch nicht, da die folgende Fehlermeldung angezeigt wird:
Bisher habe ich drei Dinge gelernt:
- Verwenden Sie zum Erstellen eines symbolischen Links unter Windows
mklink
anstelle von WSLln -s
. Öffnen Sie hierfür eine Eingabeaufforderung als Administrator. - Zum Erstellen eines symbolischen Links/einer Junction zu einem Remote-Verzeichnis müssen Sie den UNC-Pfad verwenden, nicht den Laufwerksbuchstaben.
- Die Berechtigung zum Erstellen symbolischer Links/Junctions von und zu Remoteverzeichnissen wird mit dem
fsutil
Befehl überprüftfsutil behavior query symlinkEvaluation
.
Als nächstes muss ich lernen: Wo kann ich die Berechtigungen für Symlink-/Junction-Ziele überprüfen? Hat jemand eine Idee?
Antwort1
Symlinks werden unter Linux anders implementiert als unter Windows:
- Unter Windows ist ein Symlink ein Dateitabelleneintrag, der durch Kernelaufrufe implementiert und manipuliert wird
- Unter Linux ist ein symbolischer Link einfach eine Textdatei mit einem speziellen Flag, deren Inhalt ein Pfad zum Ziel ist. (Der Pfad muss nicht einmal gültig sein.)
Dies bedeutet, dass symbolische Links (oder Symlinks), die über das Windows-Subsystem für Linux (WSL) erstellt wurden, von Windows nicht verfolgt werden können.
Windows erstellt symbolische Links mit dem mklink-Befehl.
Weitere Informationen finden Sie im Artikel
Die vollständige Anleitung zum Erstellen symbolischer Links (auch Symlinks genannt) unter Windows.
Zum Problem „Zugriff verweigert“ zitiere ich aus dem Beitrag Erstellen symbolischer Links auf Netzwerklaufwerken Teil der Antwort von GambleNerd:
Fix „Zugriff verweigert“
Wenn Sie den Befehl als Administrator ausführen
mklink /D
und derLink
Teil des Befehls ein UNC-Netzwerkpfad ist und SieAccess Denied
eine Fehlermeldung erhalten, befolgen Sie die nachstehenden Schritte, um dieses Problem möglicherweise zu beheben.
- Auf dem Server, wo(und/oder auf dem Windows-Client-PC erhalten Sie die Fehlermeldung „Zugriff verweigert“, wenn Sie den Befehl ausführen)der
Link
Teil des Befehls liegt, führen Sie diesen Befehl als Administrator auf dem Server aus:fsutil behavior query SymlinkEvaluation
- Wenn dies der Fall ist,
Remote to remote symbolic links are disabled.
führen Sie den folgenden Befehl aus:fsutil behavior set SymlinkEvaluation R2R:1
- Sie können dies von dem Ort aus ausführen, an dem Sie den MKLINK-Befehl ausführen und der Zugriff verweigert wird, sei es auf dem Windows-Server selbst oder dem Windows-Client-PC.
- Versuchen Sie nun, Ihren Befehl erneut auszuführen. Hoffentlich funktioniert er jetzt erfolgreich.
Link-Referenz: Der Zugriff auf mklink ist verweigert
Antwort2
Gibt es eine Möglichkeit, auf einem Windows-Computer Linux-ähnliche symbolische Links zu verwenden, die auf einen Speicherort auf einem anderen Computer verweisen?
Das ist möglich, aber Sie müssen UNC-Pfade anstelle von Laufwerksbuchstaben verwenden, da letztere nicht unbedingt global sind – während physische Datenträger globale Zuweisungen haben, kann jede Anmeldesitzung darüber hinaus ihre eigenen privaten Zuordnungen haben (z. B. kann Benutzer 1 Y:\ für einen Speicherort und Benutzer 2 für einen anderen Speicherort haben). Stellen Sie es sich ein bisschen so vor, als hätte jeder Benutzer seinen eigenen „Mount-Namespace“ unter Linux (pam_namespace).
Insbesondere sind alle Laufwerksbuchstaben der „zugeordneten Netzwerkfreigabe“ privat für Ihre Anmeldesitzung und werden im Kernelkontext nicht verstanden, wenn dem symbolischen Link gefolgt wird. Wenn sich das Ziel also auf einem anderen Computer befindet, müssen Sie den unverarbeiteten UNC-Pfad dafür verwenden:
cmd /c mklink /d Logs \\FileServer\Trash\Logs
Sie sollten außerdem sicherstellen, dass die Auswertung symbolischer Links von lokal zu remote nicht deaktiviert wurde fsutil behavior query symlinkEvaluation
.
wo kann ich die Berechtigungen für Symlink-/Junction-Ziele überprüfen? Hat jemand eine Idee?
Auf dem Ziel ausführen icacls
– oder im Explorer mit der rechten Maustaste darauf klicken und „Eigenschaften > Sicherheit“ wählen.
icacls \\FileServer\Trash\Logs
Auch Symlinks und Junctions unter Windowsdürfenhaben ihre eigenen Berechtigungen, die mit überprüft werden können icacls Logs /l
. Ich bezweifle, dass das das Problem sein wird, da der Link zunächst dieselben Berechtigungen erben würde wie ein normales Verzeichnis – aber es könnte sich lohnen, das zu überprüfen.
Stellen Sie also zunächst sicher, dass die Datei-/Ordnererstellung funktioniertohneSymlinks sind beteiligt, also direkt über den UNC-Pfad (oder ein zugeordnetes Laufwerk, kein Unterschied), und erst wenn das funktioniert, versuchen Sie, dasselbe über einen Symlink zu tun.
Vergessen Sie nicht: Wenn Ihre Anwendung als Dienst mit eigenen Anmeldeinformationen (Dienstkonto) ausgeführt wird, müssen diesem Konto Berechtigungen erteilt werden. Wenn sie als „NetworkService“ ausgeführt wird, müssen demMaschineKonto (FOOBAR$). (Und wenn es als „LocalService“ ausgeführt wird, hat es niemals Zugriff auf die Netzwerkfreigabe.)