Получить текущий рабочий каталог для cmd.exe
Вопрос
Как я могу получить текущий рабочий каталог 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, который всегда присутствует.Вам нужно будет иметь там какую-то структуру, чтобы возвращать успех / неудачу.
- Получите представление о процессе cmd.exe .
- Выделите там немного памяти (VirtualAllocEx)
- Поместите путь к вашей DLL-библиотеке в память.(Запись в память процесса)
- Загрузите вашу DLL-библиотеку в cmd.exe адресное пространство.(CreateRemoteThread с точкой входа LoadLibrary, аргументом является память, которую вы выделили ранее.)
- WaitForSingleObject, за которым следует GetExitCodeThread(), выдает вам HMODULE вашей библиотеки DLL в процессе cmd.exe .
- Прочитайте processmemory, чтобы получить текущий каталог.
- Выгрузите вашу dll-библиотеку из cmd.exe адресного пространства.Поток CreateRemote с точкой входа FreeLibrary, аргументом является HMODULE.
- 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 .