
建立使用者定義的右鍵點選選單項目時,Windows 註冊表中經常使用空的「NoWorkingDirectory」字串值。例如,在 Windows 資源管理器中右鍵單擊資料夾背景時能夠開啟 PowerShell(而不是右鍵單擊資料夾本身,在這種情況下不使用「NoWorkingDirectory」):
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell]
@="Open PowerShell Here"
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\Background\shell\powershell\command]
@="C:\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe -NoExit -Command Set-Location -LiteralPath '%V'"
但是,我不清楚這個值的實際用途。在我找到的所有樣本中,它始終為空。它究竟意味著什麼?
答案1
WorkingDirectory 是 System.Diagnostics.ProcessStartInfo 的屬性,當您以滑鼠右鍵按一下時,您將啟動一個新進程,此設定可讓您在目前目錄不成為「工作目錄」的情況下啟動進程。然後,它預設為正在執行的命令的 System32。
因此,當您不希望右鍵單擊的位置成為腳本運行期間環境路徑的一部分時,您可以使用「NoWorkingDirectory」。 90% 的情況下設定無用,除非您在多個路徑位置中有類似的命名文件,除非指定“NoWorkingDirectory”,否則這些文件可能會變得黏滯。
請在此處查看更多詳細資訊。
答案2
針對沒有任何程式設計技能的 Windows 使用者的簡短回答
透過右鍵點選目錄或檔案(在目錄或檔案的右側)開啟 shell 上下文選單項,執行一個(或多個)目錄/檔案名稱作為參數傳遞給執行檔的執行檔。Windows 檔案總管window)導致啟動可執行文件,並為此可執行檔設定當前工作目錄
NoWorkingDirectory
包含已點選的目錄/檔案(不存在登錄值)的目錄
或- 目錄
C:\Windows\System32
或更準確地說是Windows 註冊表中存在的%SystemRoot%\system32
註冊表值。NoWorkingDirectory
許多編碼不佳的可執行檔和腳本需要將當前工作目錄設定為包含要處理的目錄或檔案的目錄的第一個變體。這就是為什麼第一個變體是預設值的原因。
在某些情況下,第一個變體會導致不必要的行為,例如在運行時cmd.exe
處理批次腳本,該腳本將單擊的目錄/文件名作為參數傳遞,並使用其引用目錄/文件UNC 路徑。
Windows 登錄中存在的第二個變體NoWorkingDirectory
可用於所有真正編碼良好的可執行檔和腳本。
針對對細節感興趣的 Windows 使用者和程式設計師的長答案
Windows核心庫包含該函數創建進程explorer.exe
它被大多數其他可執行文件使用,能夠運行另一個可執行文件,無論是否帶有啟動訊息結構來啟動 Windows 執行檔。函數的參數之一CreateProcess
是lpCurrentDirectory
- 一個指向字串的長指針,其中的目錄路徑設定為要建立的進程的當前工作目錄。指標值也可以為空,以指示CreateProcess
使用呼叫程序的目前目錄CreateProcess
作為要建立的程序的目前工作目錄。大多數可執行程式CreateProcess
使用函數參數的空指標進行呼叫lpCurrentDirectory
。
這Windows 檔案總管( explorer.exe
) 呼叫CreateProcess
包含目錄/文件的目錄路徑,使用者使用輔助(通常是右側)指點設備(通常是滑鼠)按鈕單擊該目錄/文件,並在該項目上打開的上下文選單中單擊,從而通過按一下啟動可執行檔目錄/檔案名稱作為參數。
註冊表字串值更改有關函數參數的呼叫NoWorkingDirectory
方式的行為。目前目錄始終是存在此註冊表字串值的 Windows 系統目錄,即在大多數 Windows 電腦上擴展為.explorer.exe
CreateProcess
lpCurrentDirectory
%SystemRoot%\System32
C:\Windows\System32
可以看出如下:
請打開一個命令提示符視窗並執行以下無害命令:
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /ve /d "No working directory test"
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command" /ve /d "cmd.exe /D /C C:\Temp\DirTest\DirTest.cmd \"%V"\""
md "C:\Temp\DirTest"
echo @echo Current directory is: ^"%^CD%^">"C:\Temp\DirTest\DirTest.cmd"
echo @echo Batch file started with: %0 %*>>"C:\Temp\DirTest\DirTest.cmd"
echo @echo Command line used is: %^CMDCMDLINE%>>"C:\Temp\DirTest\DirTest.cmd"
echo @pause>>"C:\Temp\DirTest\DirTest.cmd"
這兩個reg
命令列新增到 Windows 登錄:
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest]
@="No working directory test"
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command]
@="cmd.exe /D /C \"C:\\Temp\\DirTest\\DirTest.cmd\" \"%V\""
該命令md
和四個命令列使用以下命令列echo
建立批次檔:C:\Temp\DirTest\DirTest.cmd
@echo Batch file started with: %0 %*
@echo Current directory is: "%CD%"
@echo Command line used is: %CMDCMDLINE%
@pause
現在開始Windows 檔案總管在尚未運行的情況下,在資料夾樹的左側瀏覽到該目錄C:\Windows\System32\drivers
。用滑鼠右鍵點選在右側在資料夾上etc
,然後在開啟的項目上下文功能表中按一下滑鼠左鍵無工作目錄測試之前剛剛添加到 Windows 註冊表中。
執行先前建立的批次文件,並在控制台視窗中顯示:
Current directory is: "C:\Windows\System32\drivers"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
CreateProcess
第一個輸出行顯示了on根據父行程cmd.exe
傳遞的字串從四個參數開始設定的目前目錄。可以看出,lpCurrentDirectory
explorer.exe
Windows 檔案總管CreateProcess
在這種情況下呼叫C:\Windows\System32\drivers
作為當前工作目錄路徑。
第二個輸出行顯示使用哪些參數啟動批次文件,包括參數 0,該參數是用於引用新增至 Windows 登錄中的批次檔的字串。
第三行分別輸出cmd.exe
其自身是如何啟動的。儘管儲存在登錄中,但沒有包圍在由 啟動時。explorer.exe
CreateProcess
cmd.exe
"
"
explorer.exe
註冊表字串值NoWorkingDirectory
目前不存在。這就是為什麼當前工作目錄cmd.exe
設定為右鍵單擊C:\Windows\System32\drivers
的當前目錄的原因explorer.exe
在右側etc
在目前活動資料夾所在的資料夾上Windows 檔案總管存在C:\Windows\System32\drivers
。
現在右鍵進入Windows 檔案總管 在左側在目錄的資料夾樹中,C:\Windows
同時當前活動資料夾仍然存在,C:\Windows\System32\drivers
並在項目的上下文功能表中按一下滑鼠左鍵無工作目錄測試。
又打開了一個控制台窗口,其中顯示以下幾行:
Current directory is: "C:\WINDOWS\system32"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows"
第二行和第三行符合預期。但目前目錄既不是也不C:\Windows\System32\drivers
是C:\
也不是C:\Windows
。因此可以看出,當使用者右鍵單擊目錄或虛擬 shell 資料夾左側的資料夾樹時,使用包含目錄的目錄啟動可執行檔並不總是按預期工作。
也可以看出,目前工作目錄路徑甚至不是Windows系統目錄的真實目錄路徑,因為在這種情況下將顯示C:\Windows\System32
而不是C:\WINDOWS\system32
。請注意某些字母大小寫的差異。這裡真正使用的 Windows 系統目錄路徑是SystemRoot
key 下的登錄值的串聯HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
,其中字串值C:\WINDOWS
與固定字串串聯\system32
。真實的目錄路徑是C:\Windows\System32
.
批次檔或可執行檔或任何其他設計為透過explorer.exe
上下文選單項目由類似程式執行的腳本應始終考慮到目前目錄可以是與包含傳遞的目錄/檔案名稱的目錄完全不同的目錄。進程呼叫CreateProcess
定義哪個目錄是所建立程序的目前目錄。
cmd.exe
當目前目錄路徑是 UNC 路徑時,有一個特殊的行為。在本例中,它將當前目錄變更為%SystemRoot%
(Windows 目錄)並輸出資訊:
\\ComputerName\SharedFolder\Resource
CMD.EXE 以上述路徑作為目前目錄啟動。
不支援 UNC 路徑。預設為 Windows 目錄。
這是cmd.exe
為了向下相容而完成的,因為許多可執行檔案在不以磁碟機號和冒號開頭的目前目錄路徑上無法正確運作。
可以在命令提示字元視窗中運行:
reg add "HKCU\Software\Microsoft\Command Processor" /v DisableUNCCheck /t REG_DWORD /d 1 /f
這會停用命令會話的通用命名約定 (UNC) 檢查,並cmd.exe
接受具有 UNC 路徑的目前目錄。
好的,回到註冊表值NoWorkingDirectory
。現在在命令提示字元視窗中執行:
reg add "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /v NoWorkingDirectory /t REG_SZ
新增了NoWorkingDirectory
沒有值的註冊表字串值。所以註冊表現包含在:
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest]
@="No working directory test"
"NoWorkingDirectory"=""
[HKEY_CURRENT_USER\Software\Classes\Directory\shell\NoWorkingDirectoryTest\command]
@="cmd.exe /D /C C:\\Temp\\DirTest\\DirTest.cmd \"%V\""
請注意上面發布的註冊表輸出中缺少額外的第三行。
在Windows 檔案總管右鍵點擊在左側C:\Windows
在目前活動資料夾靜止的目錄上C:\Windows\System32\drivers
,然後左鍵按一下上下文選單項無工作目錄測試完全像以前一樣。輸出又和以前一樣。所以這個用例沒有變化。
右鍵點選下一步在右側在Windows 檔案總管在目錄etc
中C:\Windows\System32\drivers
並左鍵單擊上下文選單項無工作目錄測試。將開啟一個控制台窗口,顯示以下行:
Current directory is: "C:\WINDOWS\system32"
Batch file started with: C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
Command line used is: "cmd.exe" /D /C C:\Temp\DirTest\DirTest.cmd "C:\Windows\System32\drivers\etc"
第一行顯示了與先前的註冊表字串值的重要NoWorkingDirectory
差異。當前工作目錄現在始終是使用.C:\WINDOWS\system32
C:\Windows\system32\drives
%SystemRoot%\system32
NoWorkingDirectory
新增到註冊表時不帶字串值或帶字串值(例如 )都沒有關係C:\Windows
。它甚至可以添加一個類型為DWORD
名稱、NoWorkingDirectory
值為0
或 的註冊表值1
。的登錄值類型NoWorkingDirectory
及其值對於 Windows shell ( explorer.exe
) 來說並不重要。僅當NoWorkingDirectory
Windows 註冊表中用於 shell 擴充功能的金鑰下是否存在name 的登錄值時才重要。
新增的登錄機碼和批次檔可用於更多分析,例如使用 UNC 路徑瀏覽網路資源或右鍵單擊資料夾樹左側的虛擬 shell 資料夾。也可以在C:\Temp\DirTest
具有名稱的目錄中建立Development & Test(!) 100%
並將此資料夾名稱和完整路徑傳遞給批次檔或可執行檔或其他腳本,然後看看會發生什麼。許多批次檔無法處理正確的參數字串,例如"C:\Temp\DirTest\Development & Test(!) 100%"
由於空格、感嘆號、圓括號和百分號,儘管它們是僅由 ASCII 字元組成的有效目錄名稱。
關閉透過執行開啟的所有控制台視窗後,最終應透過在命令提示字元視窗中執行以下命令來刪除註冊表項和批次檔以及用於演示行為的建立的目錄DirTest.cmd
:
reg delete "HKCU\Software\Classes\Directory\shell\NoWorkingDirectoryTest" /f
del C:\Temp\DirTest\DirTest.cmd
rd C:\Temp\DirTest
rd C:\Temp
筆記:具有檔案副檔名的捷徑檔案的許多屬性.lnk
定義了傳遞的值探險家透過CreateProcess
其函數參數和結構體STARTUPINFO
。例如房產開始於lpCurrentDirectory
定義使用捷徑檔案啟動可執行檔時最終指向的字串值。
給程式設計師的注意事項:
- C#工藝類是一個 C# 包裝類別
CreateProcess
。 - 爪哇進程建構器類是 Windows 上的 Java 包裝類別
CreateProcess
。 - 蟒蛇子流程模組是 Windows 上的 Python 包裝器模組
CreateProcess
。 - Windows 命令處理器命令支援所有透過使用它們
start
傳遞的選項,例如定義使用函數參數傳遞的字串的選項。CreateProcess
cmd.exe
/D
CreateProcess
lpCurrentDirectory
每種支援在 Windows 上執行可執行檔的程式設計和腳本語言都有一個函數或類,可以在CreateProcess
不帶或帶STARTUPINFO
結構的情況下在 Windows 上呼叫。
答案3
「NoWorkingDirectory」動詞屬性沒有記錄,所以這只是一個猜測:
Cmd.exe 不支援遠端共用 (UNC) 作為目前目錄,如果您使用這樣的工作目錄啟動 Cmd.exe,它將在控制台上列印警告訊息。
如果您查看「在此處開啟命令視窗」註冊,您將看到它使用該pushd
命令啟動 Cmd.exe 並且pushd
支援 UNC 路徑。 NoWorkingDirectory 只是為了避免顯示警告訊息。
PowerShell 其實並不需要它。