题
如何检索 cmd.exe 的当前工作目录?
这似乎是可能的。例如,使用 ProcessExplorer,选择 CMD.exe,右键单击,属性,图像选项卡,“当前目录”反映使用 CD 或 CHDIR 命令设置的目录。
我查看了 .NET Process 和 ProcessStartInfo 类(ProcessStartInfo.WorkingDirectory 始终返回“”),似乎找不到确定这一点的方法。没有什么在 调用 也很突出。
作为一个例子,我希望能够以编程方式说出类似的话:Process.GetCurrentWorkingDirectory(processID) 其中 processID 是另一个正在运行的进程的 Windows 进程 ID。
有什么解决方案吗,WinAPI 还是.NET?
[更新]
问这个问题的原因:
我已经使用“命令提示符资源管理器栏”一段时间了,它很棒,除非我“CD”到新目录,当前资源管理器窗口也不会改变。(即同步只是从资源管理器到命令提示符的一种方式)。我正在寻找两种方式。
解决方案
未经测试,一种可能的方法:
使用 DllMain 创建一个 DLL,该 DllMain 使用 GetThreadStartInformation() 查找缓冲区的地址,然后使用 GetCurrentDirectory 填充它。这应该没问题,因为这两个函数都在 kernel32 中,而 kernel32 始终存在。您需要有一些结构来返回成功/失败。
- 获取 cmd.exe 进程的句柄。
- 在那里分配一些内存(VirtualAllocEx)
- 将 DLL 的路径放入内存中。(写入进程内存)
- 将 dll 加载到 cmd.exe 地址空间中。(CreateRemoteThread,入口点为LoadLibrary,参数是您之前分配的内存。)
- WaitForSingleObject 后面跟着 GetExitCodeThread(),为您提供 cmd.exe 进程中 DLL 的 HMODULE。
- ReadProcessMemory 获取当前目录。
- 从 cmd.exe 地址空间卸载 dll。CreateRemote Thread,入口点为 FreeLibrary,参数是 HMODULE。
- WaitForSingleObject 等待 DLL 卸载。
大致草图:细节留作练习!风险:在 cmd.exe 地址空间中分配内存,更改其状态。必须小心 DllMain 中调用的函数。
其他提示
您的意思是批处理文件中的 %CD% 变量吗?
像这样:
set OLDDIR=%CD%
.. do stuff ..
chdir /d %OLDDIR% &rem restore current directory
尝试 回显%CD% 在命令提示符下。:)
因为这就是您所需要的,所以这里有一个 电源外壳 函数来做到这一点:
$(get-location)
希望这可以帮助。
我发现这一切都来自 这里.
也许这个 Sysinternals 论坛上的论坛条目 包含解决方案的提示。在 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文章“读取远程进程的环境字符串“也可能有用。
更新: 这是 不是 解决办法见这个答案的评论: “正如Janm所说,.modules [0] .fileName(或mainmoduile.filename)给出了该过程中可执行操作的位置。我希望找到当前的工作目录(可以使用CD或CHDIR命令更改)。”
你可以使用 系统.诊断命名空间. 。下面是 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);
}
}
}
}
}
这里的 输出 在我的机器上(我打开了四个命令行):
替代文本http://img236.imageshack.us/img236/3547/processworkingdirvn4.png
尝试这个简单的环境属性:
环境.CurrentDirectory()
看 我的答案 类似的问题(我自己)。我编写了一个命令行实用程序和 C# 包装器来读取进程环境变量。对于我的问题(获取 java 的当前目录),我只需读取 catalina_base 目录。
我不确定这是否直接适用于 cmd.exe。代码项目文章中提供的实用程序无法与 cmd.exe 一起使用。