Получить текущий рабочий каталог для cmd.исполняемый

Как я могу получить текущий рабочий каталог cmd.exe?

это представляется возможным. Например, используя ProcessExplorer, выберите CMD.exe, щелкните правой кнопкой мыши, свойства, вкладка "изображение", "текущий каталог" релектирует набор каталогов с помощью команд CD или CHDIR.

Я просмотрел классы .NET Process и ProcessStartInfo (ProcessStartInfo.WorkingDirectory всегда возвращает "") и, похоже, не может найти способ определить это. Ничего вызов PInvoke выделяется также.

в качестве примера я хочу программно иметь возможность сказать что-то вроде: Process.GetCurrentWorkingDirectory (processID), где processID-это идентификатор процесса Windows другого запущенного процесса.

есть ли какое-либо решение, WinAPI или .NET?

[Update]

причина задать этот вопрос:

Я использовал "панель проводника командной строки" некоторое время, и это здорово, за исключением того, что я "CD" в новый каталог, текущий Окно проводника также не изменяется. (т. е. синхронизация-это только 1 способ от проводника до командной строки). Я ищу, чтобы сделать это 2 способ.

6 ответов


непроверенный, возможный подход:

создайте DLL с DllMain, который использует GetThreadStartInformation () для поиска адреса буфера, а затем использует GetCurrentDirectory для его заполнения. Это должно быть нормально, потому что обе эти функции находятся в kernel32, который всегда присутствует. Вам нужно будет иметь некоторую структуру, чтобы вернуть успех / неудачу.

  1. получить дескриптор cmd.процесс exe.
  2. выделите там некоторую память (VirtualAllocEx)
  3. указать путь к вашей DLL в памяти. (Записи памяти процесса)
  4. загрузите dll в cmd.исполняемые адресного пространства. (CreateRemoteThread с точкой входа LoadLibrary, аргумент-это память, выделенная ранее.)
  5. WaitForSingleObject, за которым следует GetExitCodeThread (), дает вам HMODULE вашей DLL в cmd.процесс exe.
  6. ReadProcessMemory, чтобы получить текущий каталог.
  7. выгрузите dll из УМК.исполняемые адресного пространства. Поток CreateRemote с точкой входа FreeLibrary, аргументом является HMODULE.
  8. WaitForSingleObject, чтобы дождаться выгрузки DLL.

широкий эскиз: детали оставлены как упражнение! Риски: выделяет память в cmd.ехе адресное пространство, изменяет его состояние. Необходимо соблюдать осторожность с функциями, вызываемыми в DllMain.


Вы имеете в виду переменную %CD% в пакетном файле ?

такой:

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

попробовать echo %CD% в командной строке. :)

это то, что вам нужно, есть вот это PowerShell для этого:

$(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 сказал .Модули[0].имя файла или MainModuile.Именем) дает расположение исполняемого файла, запущенного в этот процесс. Я ищу, чтобы найти текущий рабочий каталог (который можно изменено с помощью CD или CHDIR команды.)"

можно использовать система.Пространство Имен Диагностики. Вот пример консоли C# приложение. Из имени файла вы можете легко извлечь информацию о пути (System.ИО.Путь...).

вы убедитесь, что у вас есть разрешения (Запуск от имени администратора) для этого.

надеюсь, что это помогает. Вот это код (проверено):

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 текст http://img236.imageshack.us/img236/3547/processworkingdirvn4.png


попробуйте это простое свойство среды:

окружающая среда.Текущей каталог()


посмотреть мой ответ: к аналогичному вопросу (сам по себе). Я написал утилиту командной строки и оболочку C# для чтения переменных среды процесса. Для моего вопроса (получение текущего dir для java) я просто читаю каталог catalina_base.

Я не уверен, что это относится непосредственно к cmd.исполняемый. Утилита, представленная в статье проекта кода не удалось работать с cmd.исполняемый.