2008-10-20 167 views
15

如何獲取cmd.exe的當前工作目錄?獲取cmd.exe的當前工作目錄

這似乎是可能的。例如,使用ProcessExplorer,選擇CMD.exe,右鍵單擊,屬性,圖像選項卡,「當前目錄」將使用CD或CHDIR命令設置目錄。

我已經看過.NET Process和ProcessStartInfo類(ProcessStartInfo.WorkingDirectory總是返回「」),並且似乎無法找到確定此方法的方法。 PInvoke也沒有什麼突出的。

作爲一個例子,我期待以編程方式能夠說類似於:Process.GetCurrentWorkingDirectory(processID)其中processID是另一個正在運行的進程的Windows進程ID。

有沒有解決方案,WinAPI或.NET?

[更新]

原因提出這個問題:

我用「命令提示符瀏覽器欄」了一段時間,這是除非我「CD」大到一個新的目錄,當前資源管理器窗口不會更改。 (即同步只是從資源管理器到命令提示符的一種方式)。我正在尋找這2種方法。

+0

你所要求的聽起來可疑。除非你正在測試(QA)或調試,否則一個進程不應該干擾另一個進程。將它用於「生產」或商業軟件是不好的,因爲它需要特權。你的產品不會得到。那麼,你想完成什麼? – jim 2008-10-20 12:23:49

+0

公平的問題。沒什麼可疑的。我已經使用了「命令提示符瀏覽器欄」一段時間,除非我「CD」到新目錄,否則當前瀏覽器窗口不會改變,這很棒。(即同步只是從資源管理器到命令提示符的一種方式)。我正在尋找這2種方法。 – Ash 2008-10-21 00:40:10

+0

我需要這個用於測試目的 - 我想殺死一個Java Tomcat進程,並將其用作區別於其他方式的一種方法。 – ripper234 2009-01-13 17:27:01

回答

5

未經檢驗的,一種可能的方法:

創建與使用GetThreadStartInformation一個DllMain中的DLL()找到緩衝區的地址,然後使用GetCurrentDirectory來填充它。這應該是可以的,因爲這兩個函數都在kernel32中,它始終存在。你將需要有一些結構來返回成功/失敗。

  1. 獲取cmd.exe進程的句柄。
  2. 在那裏分配一些內存(VirtualAllocEx)
  3. 將路徑放到內存中。 (WriteProcessMemory)
  4. 將你的dll載入cmd.exe地址空間。 (使用LoadLibrary入口點的CreateRemoteThread,參數是先前分配的內存。)
  5. WaitForSingleObject後跟GetExitCodeThread(),爲您提供cmd.exe進程中的DLL的HMODULE。
  6. ReadProcessMemory獲取當前目錄。
  7. 從cmd.exe地址空間卸載您的dll。具有FreeLibrary入口點的CreateRemote線程,參數是HMODULE。
  8. WaitForSingleObject等待DLL卸載。

寬泛的草圖:詳細信息作爲excercise!風險:在cmd.exe地址空間中分配內存,更改其狀態。必須注意DllMain中調用的函數。

+0

感謝您的詳細回覆。它看起來比說看GetProcessStrings()更復雜一點,但如果不行的話,我可能會放棄它。 – Ash 2008-10-21 00:44:28

5

你是指批處理文件中的%CD%變量嗎?

像這樣:

set OLDDIR=%CD% 
.. do stuff .. 
chdir /d %OLDDIR% &rem restore current directory 

在命令提示符下嘗試回聲%CD%。 :)

好,因爲這是你所需要的,這裏有一個PowerShell的功能來做到這一點:

$(get-location) 

希望這有助於。

我發現這一切都是從here

+0

我正在尋找編程方式能夠說類似於:Process.GetCurrentWorkingDirectory(processID)其中processID是一個Windows進程ID。 – Ash 2008-10-20 10:14:15

2

UPDATE:這是不該溶液中,使用註釋的此答案:「作爲Janm所述 .Modules [0] .FileName(或 MainModuile.FileName)給出的 位置在 這個進程中運行的可執行文件,我在尋找 當前工作目錄(可以使用CD或CHDIR 命令更改爲 )。

你可以使用System.Diagnostics命名空間。這裏以C#控制檯應用程序爲例。從文件名你可以很容易地提取路徑信息(System.IO.Path ...)。

您將確保具有權限(以管理員身份運行)來執行此操作。

希望這會有所幫助。這裏是工作代碼(測試):

using System; 
using System.Diagnostics; 
using System.IO; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Process[] procList = Process.GetProcessesByName("cmd"); 

      string sFileName; 

      for (int i = 0; i < procList.Length; i++) 
      { 
       Console.Write(procList[i].Id); 
       Console.Write(" "); 

       try 
       { 
        sFileName = procList[i].Modules[0].FileName; 
        Console.Write("("); 
        Console.Write(Path.GetFileName(sFileName)); 
        Console.Write("): "); 
        Console.WriteLine(Path.GetDirectoryName(sFileName)); 
       } 
       catch (Exception ex) 
       { 
        // catch "Access denied" etc. 
        Console.WriteLine(ex.Message); 
       } 


      } 

     } 
    } 
} 

在這裏,我的機器上輸出(我已經開了四個命令行):

alt text http://img236.imageshack.us/img236/3547/processworkingdirvn4.png

5

也許這forum entry on the Sysinternals Forum包含提示解決方案。尋找這個在GetProcessStrings功能:

// Get Command Line Block 

// At offset 0x00020498 is the process current directory followed by 

// the system PATH. After that is the process full command line, followed 

// by the exe name and the windows station it's running on. 

這CodeProject上的文章「Read Environment Strings of Remote process」可能是有用的。

0

請參閱my answer到一個類似的問題(我自己)。我編寫了一個命令行實用程序和C#包裝來讀取過程環境變量。對於我的問題(獲取當前目錄爲Java),我只是閱讀catalina_base目錄。

我不確定這是否直接適用於cmd.exe。代碼項目文章中提供的實用程序無法與cmd.exe一起使用。

1

試試這個簡單的環境屬性:

Environment.CurrentDirectory()