Вопрос

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

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

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

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

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

[Обновление]

Причина для того, чтобы задать этот вопрос:

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

Вот так:

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

Попробуй эхо %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 .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);
                }


            }

        }
    }
}

Здесь the the выходной сигнал на моей машине (я открыл четыре командные строки):

альтернативный текст http://img236.imageshack.us/img236/3547/processworkingdirvn4.png

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

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

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

Я не уверен, относится ли это непосредственно к cmd.exe .Утилита, представленная в статье Code Project, не смогла работать с cmd.exe .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top