有沒有辦法在 Windows 電腦上使用類似 Linux 的符號連結來引用另一台電腦上的位置?

有沒有辦法在 Windows 電腦上使用類似 Linux 的符號連結來引用另一台電腦上的位置?

我的應用程式正在將日誌寫入目錄,該目錄是硬編碼的“Logs”,位於我的應用程式的運行時目錄下。
今天,一位客戶問我是否可以將這些日誌放在另一個地方(另一台電腦上)。

作為第一個測試,我嘗試建立一個符號連結:

  1. 我停止了應用程式。
  2. 我刪除了「Logs」目錄。
  3. 在我的計算機上使用 WSL,我創建了一個符號鏈接,例如ln -s /mnt/c/Temp_Folder/TestLog/ /mnt/c/<Application>/Logs.
  4. 我開始了我的申請。

我沒有看到目錄中出現任何日誌C:\Temp_Folder\TestLog\

我看到不同的原因:

  • 嘗試在 Windows 電腦上使用 Linux 技術要么是一個完全愚蠢的想法。
  • 要么它可能有效,但需要考慮一些額外的事情。

我希望是第二個選擇,但那樣的話,我需要考慮哪些事情呢?

之後編輯哈利的回答:
ln -s如果您可以使用 Windows 技術(例如), 為什麼還要使用 WSL mklink? :-)

我喜歡這個想法,但不幸的是它似乎不起作用,正如您從以下實驗中看到的那樣:

C:\<Runtime_Dir>mklink /D Logs E:\TestLog\
=> result:
29/03/2024  08:21    <SYMLINKD>     Logs [E:\TestLog\]

=> 因此,確實Logs創建了目錄符號鏈接,但是當我啟動應用程式時,似乎不再寫入任何日誌(我看到它們是在控制台視窗中創建的,但它們沒有寫在文件中)。

其他一些實驗:(我記得之前有一個路口,但細節已經忘記了)

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.

經過更多實驗後編輯2:
在引用另一個驅動器時,它似乎不起作用,但當我引用同一台電腦上的另一個目錄時,它似乎確實起作用,如下所示:

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\

我可以確認,在這兩種情況下,日誌都會被建立!

換句話說,問題不在於 Windows 符號連結/連接不起作用:問題在於符號連結/連接引用了另一個驅動器。
我記得在 Windows 中創建驅動器有兩種甚至三種方法(驅動器映射、替換(?)和另一種(???),這在我的腦海中非常模糊),我想知道符號鏈接/連接故事是否可以在一種驅動器上工作,但不能在另一種驅動器上工作,以及是否有辦法解決這個問題。

回答後編輯3u1686_重力:
即使使用 UNC 路徑並具有“正確”的配置行為,它似乎仍然不起作用:

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\

連結已創建,但那裡沒有創建日誌檔案。

因此,因為我認為我的方向是正確的,所以我決定執行另一個測試:使用 Windows 資源管理器進入Logs目錄/符號連結/連接點並使用資源管理器的上下文功能表建立簡單的文字檔案。這不起作用,因為出現以下錯誤訊息:

在此輸入影像描述

到目前為止我學到了三件事:

  1. 要在 Windows 上建立符號鏈接,請使用mklink而不是 WSL 的ln -s.為此以管理員身份開啟命令提示字元。
  2. 若要建立到遠端目錄的符號連結/連接,您需要使用 UNC 路徑,而不是磁碟機號碼。
  3. fsutil使用命令檢查從遠端目錄建立符號連結/連接到遠端目錄的權限fsutil behavior query symlinkEvaluation

接下來我需要學習:在哪裡檢查符號連結/連接目標權限?有人有想法嗎?

答案1

Linux 上符號連結的實作方式與 Windows 上不同:

  • 在 Windows 上,符號連結是由核心呼叫實作和操作的檔案表條目
  • 在 Linux 上,符號連結只是一個帶有特殊標誌的文字文件,其內容是目標的路徑。 (該路徑甚至不必有效。)

這意味著 Windows 無法追蹤透過 Windows Linux 子系統 (WSL) 建立的符號連結。

Windows 使用以下命令建立符號鏈接 mklink命令

欲了解更多信息,請參閱文章
在 Windows 上建立符號連結(又稱符號連結)的完整指南


對於“拒絕訪問”的問題,我引用一下帖子 在網路磁碟機上建立符號鏈接 的一部分 GambleNerd 的回答:

訪問拒絕修復

mklink /D如果您以管理員身分執行該命令,且Link 該命令的一部分是 UNC 網路路徑,並且您收到Access Denied 錯誤訊息,請依照下列步驟操作可能會解決此問題。

  1. 在伺服器上(和/或在 Windows 用戶端 PC 上執行命令時,您會收到「存取被拒絕」錯誤訊息)該命令的部分 Link位於,在伺服器上以管理員身份執行此命令:fsutil behavior query SymlinkEvaluation
  2. 如果您看到Remote to remote symbolic links are disabled.則執行以下命令:fsutil behavior set SymlinkEvaluation R2R:1
  • 您可以從執行 MKLINK 命令的位置執行此命令,並且無論是在 Windows Server 本身還是 Windows 用戶端 PC 上存取都會被拒絕
  1. 現在嘗試再次運行您的命令,希望它現在可以成功運行。

連結參考: mklink 上的存取被拒絕

答案2

有沒有辦法在 Windows 電腦上使用類似 Linux 的符號連結來引用另一台電腦上的位置?

這是可能的,但您需要使用UNC 路徑而不是磁碟機號,因為後者不一定是全域的- 雖然實體磁碟區具有全域分配,但每個登入工作階段都可以在其之上有自己的私有對應(例如,使用者1 可以有 Y :\ 代表一個位置,使用者 2 可以讓它代表另一個位置)。可以把它想像成每個使用者在 Linux 上都有自己的「掛載命名空間」(pam_namespace)。

具體來說,所有「映射網路共用」磁碟機號碼對於您的登入工作階段都是私有的,並且在遵循符號連結時在核心上下文中不會被理解。因此,如果目標位於另一台電腦上,則需要為其使用原始 UNC 路徑:

cmd /c mklink /d Logs \\FileServer\Trash\Logs

您還應該確保本地到遠端符號連結評估尚未通過fsutil behavior query symlinkEvaluation.

在哪裡檢查符號連結/連接目標權限?有人有想法嗎?

icacls在目標上運行– 或在資源管理器中右鍵單擊它並轉到“屬性 > 安全性”。

icacls \\FileServer\Trash\Logs

此外,Windows 上的符號連結和連接有自己的權限,可以使用 來檢查icacls Logs /l。我懷疑這會是問題所在,因為連結最初會繼承與普通目錄相同的權限 - 但可能值得檢查。

因此,首先確保文件/資料夾創建有效沒有涉及符號鏈接,即直接通過 UNC 路徑(或映射驅動器,沒有區別),並且只有在您完成該工作後,才嘗試通過符號鏈接執行相同的操作。

不要忘記,如果您的應用程式作為服務運行,並具有自己的憑證(服務帳戶),則必須向該帳戶授予權限;如果它是作為“NetworkService”運行,則必須授予權限機器帳戶(FOOBAR$)。 (如果它是作為“LocalService”運行,它將永遠不會具有網路共享存取權。)

相關內容