如何检索 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 始终存在。您需要有一些结构来返回成功/失败。

  1. 获取 cmd.exe 进程的句柄。
  2. 在那里分配一些内存(VirtualAllocEx)
  3. 将 DLL 的路径放入内存中。(写入进程内存)
  4. 将 dll 加载到 cmd.exe 地址空间中。(CreateRemoteThread,入口点为LoadLibrary,参数是您之前分配的内存。)
  5. WaitForSingleObject 后面跟着 GetExitCodeThread(),为您提供 cmd.exe 进程中 DLL 的 HMODULE。
  6. ReadProcessMemory 获取当前目录。
  7. 从 cmd.exe 地址空间卸载 dll。CreateRemote Thread,入口点为 FreeLibrary,参数是 HMODULE。
  8. 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 一起使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top