[英]current working directory in a vbscript invoked by a drag & drop operation
當我試圖獲得我的批處理腳本的提升權限時,我發現了兩個相關的SO問題
......這導致了部分解決的問題。 出於某種原因,我遇到了在VBS腳本中包含空格的文件路徑參數的命令行傳遞問題,所以我試圖將解決方案分成3部分並集中在內部(VBS)步驟,然后通過調用a添加最后一步盡管與VBS腳本位於同一文件夾中,但無法找到該VBS中的批處理。 我發現拖放不是那么“容易”, 並且使用.vbs
而不是.bat
或.exe
作為放置目標時會有所不同。
如果我拖動文件並將其拖放到可執行文件(exe)或批處理文件(bat,cmd)上,則當前工作目錄由拖動項目的來源確定。 其目錄設置為處理它的程序或腳本的工作目錄。
如果我將文件放到VBS腳本上,則會有所不同。 在Windows 8.1 x64上,我發現它是C:\\Windows\\System32
即使參數與VBS位於同一文件夾中。
我可以簡單地使用這樣的批處理文件(如拖放中繼)
my.vbs %*
獲得“正常” .bat
行為(drop source指示CWD),但我也想了解它。
這是一個錯誤還是一個功能? 它是否與所有Windows版本一致?
編輯:為顯示我如何到達的問題添加背景(在頂部)(+次要更正)
經過一些API監控,這就是我所看到的
將文件放在.exe
文件上時, explorer.exe
使用CreateProcess
API函數啟動進程,將可執行文件作為lpApplicationName
傳遞,將可執行文件和已刪除文件作為lpCommandLine
。 lpCurrentDirectory
在調用者進程的函數調用中設置為包含刪除文件[1]的文件夾。
將文件放在.cmd
文件上時, explorer.exe
也使用CreateProcess
API,但在這種情況下, lpApplicationName
為null
, lplCommandLine
包含批處理文件和刪除的文件。 lpCurrentDirectory
也設置為刪除文件[1]的父文件夾。
將文件放在.vbs
文件上時,使用ShellExecuteEx
且SHELLEXECUTEINFO
結構的lpDirectory
字段為null
,因此,創建的進程將繼承父進程的當前活動目錄。 默認情況下, explorer.exe
進程的當前活動目錄是%systemroot%\\system32
,但是可以啟動具有不同當前活動目錄的explorer
實例,該目錄將在此類刪除操作中繼承。
[1]如果我們刪除多個文件,則使用作為第一個參數傳遞的文件的路徑
請注意僅供參考:測試活動目錄繼承后面的過程是:
cmd
實例並將當前活動目錄更改為c:\\temp
explorer.exe
實例 cmd
實例調用explorer.exe
。 此explorer
實例將cmd
窗口中的活動目錄作為其當前活動目錄。 Arguments
屬性包含腳本上刪除的所有項的完整路徑,因此您可以確定每個已刪除項的目錄,如下所示:
Set fso = CreateObject("Scripting.FileSystemObject")
For Each item In WScript.Arguments
WScript.Echo fso.GetParentFolderName(item)
Next
假設工作目錄將被刪除到腳本上的內容定義,這是一種誤導的方法。 如果您需要該邏輯,您可以自己在腳本中實現它,例如,像這樣:
Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("WScript.Shell")
For Each item In WScript.Arguments
sh.CurrentDirectory = fso.GetParentFolderName(item)
'working directory is now the parent folder of the current item
'...
Next
如果您需要工作目錄作為VBScript文件的父目錄,您可以從ScriptFullName
屬性派生它:
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetParentFolderName(WScript.ScriptFullName)
如果我在Windows注冊表中查找文件類型,我在其Shell\\Open\\Command
值中看到以下內容:
"%1" %*
"%1" %*
"%1" %*
"%SystemRoot%\\System32\\WScript.exe" "%1" %*
這似乎表明bat
, cmd
, exe
本身被視為可執行文件 ,可能是出於歷史原因,而VBS被認為是普通腳本 ,只能執行,因為它的擴展名是注冊一些可執行文件來調用它。 與Python或Perl幾乎相同。
[更新]事實上我證明了Python腳本顯示的行為與我的VBS腳本完全相同:從命令行調用它提供參數保持CWD,在其上刪除文件導致CWD為C:\\Windows\\System32
。 所以我的問題似乎有點不對,但最后它幫助人們指出了進一步研究的正確方向......
c:\\windows\\system32\\CScript.exe
或c:\\windows\\system32\\Wscript.exe
是運行vbscript的程序。 如您所見,它們位於system32
。
Windows使用ShellExecuteEx啟動程序 - 請參閱MSDN上的規則:
ShellExecuteEx函數(Windows)
ShellExecuteEx使用CreateProcess(CreateProcessEx)來實際啟動程序。 CreateProcess函數(Windows)
編輯
CMD不會將注冊表用於它自己的東西。 這些注冊表項是針對CMD以外的程序。
CMD的主要目標是在增強它的同時兼容MS Dos 5,它將正確運行大多數DOS批處理文件。 它是由在OS / 2 NOT Windows上工作的IBM工程師編寫的。
編輯2
您的問題的核心是您正在嘗試編寫程序,就像您是用戶鍵入操作計算機一樣。
作為一名程序員,你不做假設。 不采取假設的最簡單方法是指定所需的完整路徑 。 您的批處理文件不應該關心當前目錄是什么。 EG在CMD中,每個驅動器都有一個當前目錄,用於與MSDos 5兼容(並且控制台中的程序傾向於共享它們但不必共享它們)。 在Windows中,每個程序有一個當前目錄。 多年來,默認的當前目錄已更改。
您應該使用當前目錄的唯一時間是編寫批處理文件供用戶使用。 EG如果你鍵入dir
它會執行當前目錄,那么作為常規命令的批處理文件應該以相同的方式工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.