获取cmd.exe的当前工作目录

发布于 2024-07-08 14:26:33 字数 606 浏览 3 评论 0原文

如何检索 cmd.exe 的当前工作目录?

这似乎是可能的。 例如,使用 ProcessExplorer,选择 CMD.exe,右键单击,属性,图像选项卡,“当前目录”反映使用 CD 或 CHDIR 命令设置的目录。

我查看了 .NET Process 和 ProcessStartInfo 类(ProcessStartInfo.WorkingDirectory 始终返回“”),似乎找不到确定这一点的方法。 PInvoke 也没有什么突出的地方。

作为一个例子,我希望能够以编程方式说出类似的内容: Process.GetCurrentWorkingDirectory(processID) 其中 processID 是另一个正在运行的进程的 Windows 进程 ID。

有什么解决方案吗,WinAPI 还是.NET?

[更新]

提出这个问题的原因:

我已经使用“命令提示符资源管理器栏”一段时间了,它很棒,除非我“CD”到新目录,当前资源管理器窗口也不会改变。 (即同步只是从资源管理器到命令提示符的一种方式)。 我正在寻找两种方式。

How can I retrieve the current working directory of cmd.exe?

This seems possible. For example using ProcessExplorer, select CMD.exe, right click, properties, Image tab, "Current Directory" relects the directory set using the CD or CHDIR commands.

I've looked at the .NET Process and ProcessStartInfo classes (ProcessStartInfo.WorkingDirectory always returns "") and can't seem to find a way of determining this. Nothing at PInvoke stands out either.

As an example I'm looking to programmatically be able to say something like: Process.GetCurrentWorkingDirectory(processID) where processID is a Windows process ID of another running process.

Is there any solution, WinAPI or .NET?

[Update]

Reason for asking this question:

I've used the "Command Prompt Explorer Bar" for a while and it's great except if I "CD" to a new directory, the current Explorer window does not also change. (ie the Sync is only 1 way from Explorer to the commmand prompt). I'm looking to make this 2 way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月朦胧 2024-07-15 14:26:33

未经测试,一种可能的方法:

创建一个带有 DllMain 的 DLL,该 DllMain 使用 GetThreadStartInformation() 查找缓冲区的地址,然后使用 GetCurrentDirectory 填充它。 这应该没问题,因为这两个函数都在 kernel32 中,而 kernel32 始终存在。 您需要有一些结构来返回成功/失败。

  1. 获取 cmd.exe 进程的句柄。
  2. 在那里分配一些内存 (VirtualAllocEx)
  3. 将 DLL 的路径放入内存中。 (WriteProcessMemory)
  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 中调用的函数。

Untested, a possible approach:

Create a DLL with a DllMain that uses GetThreadStartInformation() to find the address of the buffer, and then uses GetCurrentDirectory to populate it. This should be OK, because both of those functions are in kernel32, which is always present. You will need to have some structure there to return success/failure.

  1. Get a handle to the cmd.exe process.
  2. Allocate some memory there (VirtualAllocEx)
  3. Put the path to your DLL in the memory. (WriteProcessMemory)
  4. Load your dll into the cmd.exe address space. (CreateRemoteThread with an entry point of LoadLibrary, the argument is the memory you allocated earlier.)
  5. WaitForSingleObject followed by GetExitCodeThread(), gives you the HMODULE of your DLL in the cmd.exe process.
  6. ReadProcessMemory to get the current directory.
  7. Unload your dll from the cmd.exe address space. CreateRemote Thread with an entry point of FreeLibrary, the argument is the HMODULE.
  8. WaitForSingleObject to wait for the DLL to unload.

Broad sketch: Details left as an excercise! Risks: Allocates memory in the cmd.exe address space, changes its state. Care must be taken with the functions called in DllMain.

悍妇囚夫 2024-07-15 14:26:33

您的意思是批处理文件中的 %CD% 变量吗?

像这样:

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

尝试在命令提示符中echo %CD%。 :)

因为这正是您所需要的,这里有一个 PowerShell 函数可以做到这一点:

$(get-location)

希望这会有所帮助。

我从这里找到了这一切。

Do you mean the %CD% variable in a batch file ?

Like this:

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

Try echo %CD% in a command prompt. :)

Well as this is what you need, there here is a PowerShell function to do it:

$(get-location)

Hope this helps.

I found it all from here.

夕色琉璃 2024-07-15 14:26:33

也许这个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 文章“读取远程进程的环境字符串”也可能有用。

Maybe this forum entry on the Sysinternals Forum contains a hint to the solution. Look for this in the GetProcessStrings function:

// 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.

This CodeProject article "Read Environment Strings of Remote process" could be useful too.

巾帼英雄 2024-07-15 14:26:33

更新:不是解决方案,请参阅此答案的评论:“正如 Janm 所说
.Modules[0].FileName(或
MainModuile.FileName) 给出
运行的可执行文件的位置
那个过程。 我正在寻找
当前工作目录(可以是
使用 CD 或 CHDIR 进行更改
命令)。”

您可以使用System.Diagnostics Namespace。这里是 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

UPDATE: This is not the solution, see the comments to this answer: "As Janm said
.Modules[0].FileName (or
MainModuile.FileName) gives the
location of the executable running in
that process. I'm looking to find the
current working directory (that can be
changed using the CD or CHDIR
commands)."

You could use System.Diagnostics Namespace. Here an example as C# console application. From the filename you can easily extract the Path information (System.IO.Path...).

You would make sure to have the permissions (run as admin) to do this.

Hope this helps. Here is the working code (tested):

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);
                }


            }

        }
    }
}

Here the the output on my machine (I've opened four command lines):

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

偷得浮生 2024-07-15 14:26:33

尝试这个简单的环境属性:

Environment.CurrentDirectory()

Try this simple environment property:

Environment.CurrentDirectory()

清醇 2024-07-15 14:26:33

请参阅我对类似问题的回答(我自己)。 我编写了一个命令行实用程序和 C# 包装器来读取进程环境变量。 对于我的问题(获取 java 的当前目录),我只需读取 catalina_base 目录。

我不确定这是否直接适用于 cmd.exe。 代码项目文章中提供的实用程序无法与 cmd.exe 一起使用。

See my answer to a similar question (by myself). I wrote a command line utility and C# wrapper to read the process environment variables. For my question (getting current dir for java), I simply read the catalina_base directory.

I'm not sure if this applies directly to cmd.exe. The utility provided in the Code Project article failed to work with cmd.exe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文