Pregunta

¿Cómo puedo recuperar el directorio de trabajo actual de cmd.exe?

Esto parece posible. Por ejemplo, utilizando ProcessExplorer, seleccione CMD.exe, haga clic con el botón derecho, propiedades, pestaña Imagen, " Directorio actual " vuelve a conectar el conjunto de directorios utilizando los comandos CD o CHDIR.

He examinado las clases .NET Process y ProcessStartInfo (ProcessStartInfo.WorkingDirectory siempre devuelve " ") y parece que no puede encontrar una forma de determinar esto. Nada en PInvoke tampoco se destaca.

Como ejemplo, estoy buscando poder decir algo así como: Process.GetCurrentWorkingDirectory (processID) donde processID es un ID de proceso de Windows de otro proceso en ejecución.

¿Hay alguna solución, WinAPI o .NET?

[Actualización]

Motivo para hacer esta pregunta:

He usado la " Barra de Explorador de símbolo del sistema " por un tiempo y es genial, excepto si I " CD " a un nuevo directorio, la ventana actual del Explorador no cambia también. (es decir, la sincronización es solo de 1 forma desde Explorer hasta el indicador de comando). Estoy buscando hacer esto de 2 maneras.

¿Fue útil?

Solución

No probado, un posible enfoque:

Cree una DLL con un DllMain que use GetThreadStartInformation () para encontrar la dirección del búfer y luego use GetCurrentDirectory para llenarlo. Esto debería estar bien, ya que ambas funciones están en kernel32, que siempre está presente. Deberá tener alguna estructura allí para devolver el éxito / fracaso.

  1. Obtenga un identificador para el proceso cmd.exe.
  2. Asignar algo de memoria allí (VirtualAllocEx)
  3. Ponga la ruta a su DLL en la memoria. (WriteProcessMemory)
  4. Cargue su dll en el espacio de direcciones cmd.exe. (CreateRemoteThread con un punto de entrada de LoadLibrary, el argumento es la memoria que asignó anteriormente).
  5. WaitForSingleObject seguido de GetExitCodeThread (), le proporciona el HMODULE de su DLL en el proceso cmd.exe.
  6. ReadProcessMemory para obtener el directorio actual.
  7. Descargue su dll del espacio de direcciones cmd.exe. CreateRemote Thread con un punto de entrada de FreeLibrary, el argumento es el HMODULE.
  8. WaitForSingleObject para esperar a que se descargue la DLL.

Boceto amplio: ¡Detalles que se dejan como ejercicio! Riesgos: Asigna memoria en el espacio de direcciones cmd.exe, cambia su estado. Se debe tener cuidado con las funciones llamadas en DllMain.

Otros consejos

¿Se refiere a la variable% CD% en un archivo por lotes?

Me gusta esto:

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

Pruebe echo% CD% en un símbolo del sistema. :)

Bueno, como esto es lo que necesita, aquí hay una función PowerShell para hacerlo:

$(get-location)

Espero que esto ayude.

Lo encontré todo en aquí .

Tal vez esta entrada del foro en el Foro de Sysinternals contiene una sugerencia para solución. Busque esto en la función 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.

Este artículo de CodeProject " Leer cadenas de entorno del proceso remoto " También podría ser útil.

  

ACTUALIZACIÓN: Esta no es la solución, vea los comentarios a esta respuesta: " Como dijo Janm   .Módulos [0] .FileName (o   MainModuile.FileName) da el   ubicación del ejecutable que se ejecuta en   ese proceso Estoy buscando para encontrar el   directorio de trabajo actual (que puede ser   cambiado usando el CD o CHDIR   comandos). "

Puedes usar System.Diagnostics Namespace . Aquí un ejemplo como aplicación de consola C #. Desde el nombre del archivo puede extraer fácilmente la información de la ruta (System.IO.Path ...).

Asegúrate de tener los permisos (ejecutar como administrador) para hacer esto.

Espero que esto ayude. Aquí está el código de trabajo (probado):

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


            }

        }
    }
}

Aquí el resultado en mi máquina (he abierto cuatro líneas de comando):

texto alternativo http://img236.imageshack.us/img236/3547/processworkingdirvn4 .png

Pruebe esta propiedad de entorno simple:

Environment.CurrentDirectory ()

Consulte mi respuesta a una pregunta similar (por mi cuenta). Escribí una utilidad de línea de comandos y un contenedor de C # para leer las variables de entorno del proceso. Para mi pregunta (obtener el directorio actual para java), simplemente leí el directorio catalina_base.

No estoy seguro de si esto se aplica directamente a cmd.exe. La utilidad provista en el artículo de Code Project no funcionó con cmd.exe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top