簡體   English   中英

通過拖放操作調用的vbscript中的當前工作目錄

[英]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,但在這種情況下, lpApplicationNamenulllplCommandLine包含批處理文件和刪除的文件。 lpCurrentDirectory也設置為刪除文件[1]的父文件夾。

將文件放在.vbs文件上時,使用ShellExecuteExSHELLEXECUTEINFO結構的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值中看到以下內容:

  • batfile: "%1" %*
  • cmdfile: "%1" %*
  • exefile: "%1" %*
  • VBSFile: "%SystemRoot%\\System32\\WScript.exe" "%1" %*

這似乎表明batcmdexe本身被視為可執行文件 ,可能是出於歷史原因,而VBS被認為是普通腳本 ,只能執行,因為它的擴展名是注冊一些可執行文件來調用它。 與Python或Perl幾乎相同。

[更新]事實上我證明了Python腳本顯示的行為與我的VBS腳本完全相同:從命令行調用它提供參數保持CWD,在其上刪除文件導致CWD為C:\\Windows\\System32 所以我的問題似乎有點不對,但最后它幫助人們指出了進一步研究的正確方向......

c:\\windows\\system32\\CScript.exec:\\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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM