Pergunta

Como posso recuperar o diretório de trabalho atual do cmd.exe?

Isto parece possível.Por exemplo, usando ProcessExplorer, selecione CMD.exe, clique com o botão direito, propriedades, guia Imagem, "Diretório Atual" seleciona o diretório definido usando os comandos CD ou CHDIR.

Examinei as classes .NET Process e ProcessStartInfo (ProcessStartInfo.WorkingDirectory sempre retorna "") e não consigo encontrar uma maneira de determinar isso.Nada em PInvoke se destaca também.

Por exemplo, procuro programaticamente ser capaz de dizer algo como:Process.GetCurrentWorkingDirectory(processID) onde processID é um ID de processo do Windows de outro processo em execução.

Existe alguma solução, WinAPI ou .NET?

[Atualizar]

Razão para fazer esta pergunta:

Eu usei a "Barra do Explorer do prompt de comando" por um tempo e é ótima, exceto se eu "CD" para um novo diretório, a janela atual do Explorer também não muda.(ou seja, a sincronização ocorre apenas em um caminho do Explorer até o prompt de comando).Estou tentando fazer isso de 2 maneiras.

Foi útil?

Solução

Não testado, uma possível abordagem:

Crie uma DLL com um dllmain que usa getThreadStartInformation () para encontrar o endereço do buffer e, em seguida, usa o GetCurrentDirectory para preenchê -lo. Isso deve ser bom, porque ambas as funções estão no kernel32, o que está sempre presente. Você precisará ter alguma estrutura para retornar o sucesso/falha.

  1. Obtenha um identificador no processo cmd.exe.
  2. Alocar alguma memória lá (VirtualAlocex)
  3. Coloque o caminho para sua DLL na memória. (WriteProcessMemory)
  4. Carregue sua DLL no espaço de endereço cmd.exe. (CreateremoteThread com um ponto de entrada de biblioteca de carga, o argumento é a memória que você alocou anteriormente.)
  5. WaitforsingleObject seguido pelo getExitCodethRead (), fornece o hmodule da sua DLL no processo cmd.exe.
  6. ReadProcessMemory para obter o diretório atual.
  7. Descarregue sua DLL no espaço de endereço cmd.exe. Tópico Createremote com um ponto de entrada da biblioteca, o argumento é o hmodule.
  8. WaitForSingleObject para esperar a DLL descarregar.

Esboço Broad: Detalhes deixados como um exercício! Riscos: aloca a memória no espaço de endereço cmd.exe, altera seu estado. Deve -se tomar cuidado com as funções chamadas no DLLMain.

Outras dicas

Você quer dizer a variável % CD % em um arquivo em lote?

Assim:

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

Tentar eco %CD % em um prompt de comando. :)

Bem como é isso que você precisa, aqui está um PowerShell função para fazer isso:

$(get-location)

Espero que isto ajude.

Eu encontrei tudo de aqui.

Talvez isto Entrada do fórum no fórum Sysinternals contém uma dica para a solução. Procure isso na função 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 artigo do CodeProject "Leia seqüências de ambiente de processo remoto"Pode ser útil também.

ATUALIZAR: Isto é não A solução, veja os comentários para esta resposta: "Como Janm disse .Modules [0] .FileName (ou mainmoduile.fileName) fornece a localização do executável em execução nesse processo. Estou procurando encontrar o diretório de trabalho atual (que pode ser alterado usando os comandos CD ou CHDIR) . "

Você poderia usar System.Diagnostics Namespace. Aqui um exemplo como aplicativo de console C#. Do nome do arquivo, você pode extrair facilmente as informações do caminho (System.io.Path ...).

Você se certificaria de ter as permissões (executadas como administrador) para fazer isso.

Espero que isto ajude. Aqui está o Código de trabalho (testado):

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


            }

        }
    }
}

Aqui o resultado Na minha máquina (abri quatro linhas de comando):

TEXTO DE ALT HTTP://img236.imageshack.us/img236/3547/processworkingdirvn4.png

Experimente esta propriedade de ambiente simples:

Environment.CurrentDirectory ()

Ver minha resposta para uma pergunta semelhante (por mim mesmo).Eu escrevi um utilitário de linha de comando e um wrapper C# para ler as variáveis ​​de ambiente do processo.Para minha pergunta (obter o diretório atual para java), simplesmente li o diretório catalina_base.

Não tenho certeza se isso se aplica diretamente ao cmd.exe.O utilitário fornecido no artigo Code Project não funcionou com cmd.exe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top