Pergunta

Como faço para encontrar o caminho do aplicativo em um aplicativo do console?

Na Windows Forms , posso usar Application.StartupPath para encontrar o caminho atual, mas este doesn' t parecem estar disponíveis em um aplicativo de console.

Foi útil?

Solução

System.Reflection.Assembly.GetExecutingAssembly() . Location 1

Combine isso com System.IO.Path.GetDirectoryName se tudo você quer é o diretório.

1 De acordo com o comentário de Mr.Mindor:
retornos System.Reflection.Assembly.GetExecutingAssembly().Location onde o conjunto de execução está actualmente localizado, o qual pode ou não ser onde a montagem está localizada quando não em execução. No caso dos conjuntos de cópia de sombra, você vai ter um caminho em um diretório temporário. System.Reflection.Assembly.GetExecutingAssembly().CodeBase irá retornar o caminho 'permanente' de a montagem.

Outras dicas

Você pode usar o seguinte código para obter o diretório do aplicativo atual.

AppDomain.CurrentDomain.BaseDirectory

Você tem duas opções para encontrar o diretório do aplicativo, que você escolheu vai depender do seu propósito.

// to get the location the assembly is executing from
//(not necessarily where the it normally resides on disk)
// in the case of the using shadow copies, for instance in NUnit tests, 
// this will be in a temp directory.
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;

//To get the location the assembly normally resides on disk or the install directory
string path = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

//once you have the path you get the directory with:
var directory = System.IO.Path.GetDirectoryName(path);

Provavelmente um pouco tarde, mas esta é uma menção a pena:

Environment.GetCommandLineArgs()[0];

ou mais corretamente para obter apenas o caminho do diretório:

System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);

Editar:

Muito poucas pessoas têm apontado que GetCommandLineArgs não é garantida para retornar o nome do programa. Consulte A primeira palavra na linha de comando é o nome do programa apenas por convenção . O artigo faz afirmar que "Embora extremamente alguns programas do Windows usar esta peculiaridade (eu não tenho conhecimento de qualquer eu)". Por isso, é possível 'spoof' GetCommandLineArgs, mas estamos a falar de um aplicativo de console. aplicações de console são geralmente rápido e sujo. Então isso se encaixa com a minha filosofia KISS.

Para alguém interessado em aplicativos da Web ASP.NET. Aqui estão os meus resultados de 3 métodos diferentes

protected void Application_Start(object sender, EventArgs e)
{
  string p1 = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  string p2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
  string p3 = this.Server.MapPath("");
  Console.WriteLine("p1 = " + p1);
  Console.WriteLine("p2 = " + p2);
  Console.WriteLine("p3 = " + p3);
}

Resultado

p1 = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\a897dd66\ec73ff95\assembly\dl3\ff65202d\29daade3_5e84cc01
p2 = C:\inetpub\SBSPortal_staging\
p3 = C:\inetpub\SBSPortal_staging

o aplicativo está sendo executado fisicamente de "C: \ inetpub \ SBSPortal_staging"., Então a primeira solução não é definitivamente apropriar para aplicações web

A resposta acima foi de 90% do que eu precisava, mas retornou um Uri vez de um caminho regular para mim.

Como explicado nos fóruns MSDN postar, Como converter caminho URI para filepath normais , eu usei o seguinte:?

// Get normal filepath of this assembly's permanent directory
var path = new Uri(
    System.IO.Path.GetDirectoryName(
        System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
    ).LocalPath;

Você pode estar procurando para fazer isso:

System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

Você pode usar este em vez.

System.Environment.CurrentDirectory

para aplicativos de console, você pode tentar o seguinte:

System.IO.Directory.GetCurrentDirectory();

Saída (na minha máquina local):

c: \ users \ xxxxxxx \ documentos \ Visual Studio 2012 \ Projects \ imagehandler \ GetDir \ bin \ Debug

Ou você pode tentar (há uma barra adicional no final):

AppDomain.CurrentDomain.BaseDirectory

Output:

c: \ users \ xxxxxxx \ documentos \ Visual Studio 2012 \ Projects \ imagehandler \ GetDir \ bin \ Debug \

Eu tenho usado este código e obter a solução.

AppDomain.CurrentDomain.BaseDirectory

Se você está procurando uma maneira compatível com .NET Core, uso

System.AppContext.BaseDirectory

Este foi introduzido no .NET Framework 4.6 e .NET Núcleo 1.0 (e .NET padrão 1.3). Veja: AppContext.BaseDirectory Propriedade .

De acordo com a esta página ,

Este é o substituto preferido para AppDomain.CurrentDomain.BaseDirectory em .NET Núcleo

Eu tenho usado

System.AppDomain.CurrentDomain.BaseDirectory

Quando eu quero encontrar um caminho relativo para uma pasta de aplicativos. Isso funciona tanto para ASP.Net e aplicativos winform. Ele também não exige qualquer referência aos conjuntos System.Web.

Você pode simplesmente adicionar ao seu projeto referências System.Windows.Forms e depois usar o System.Windows.Forms.Application.StartupPath como de costume.

Assim, não precisa de métodos mais complicados ou usando a reflexão.

Eu uso isso se o exe é suposto ser chamado com um clique duplo-lo

var thisPath = System.IO.Directory.GetCurrentDirectory();

Quer dizer, por que não um P / Invoke método?

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    public class AppInfo
    {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
            private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
            private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
            public static string StartupPath
            {
                get
                {
                    StringBuilder stringBuilder = new StringBuilder(260);
                    GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
                    return Path.GetDirectoryName(stringBuilder.ToString());
                }
            }
    }

Você poderia usá-lo apenas como o Application.StartupPath:

    Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");

Seguindo a linha vai lhe dar um caminho do aplicativo:

var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

solução acima está funcionando corretamente no seguinte situações:

  • aplicativo simples
  • em outro domínio onde Assembly.GetEntryAssembly () deve retornar nulo
  • DLL é carregado a partir de recursos incorporados como matriz de bytes e carregado para AppDomain como Assembly.Load (byteArrayOfEmbeddedDll)

Assembly.GetEntryAssembly().Location ou Assembly.GetExecutingAssembly().Location

Use em combinação com System.IO.Path.GetDirectoryName() para obter apenas o diretório.

Os caminhos de GetEntryAssembly() e GetExecutingAssembly() pode ser diferente, embora para a maioria dos casos, o diretório será o mesmo.

Com GetEntryAssembly() você tem que estar ciente de que isso pode voltar null se o módulo de entrada é não gerenciado (ou seja, C ++ ou VB6 executável). Nesses casos, é possível usar GetModuleFileName da API Win32:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
AppDomain.CurrentDomain.BaseDirectory

resolverá o problema para se referir os arquivos 3º referência festa com pacotes de instalação.

no VB.net

My.Application.Info.DirectoryPath

funciona para mim (Aplicação Tipo: Class Library). Não tenho certeza C # ... Retorna o caminho w / o nome do arquivo como seqüência

Nenhum desses métodos funcionam em casos especiais como usar um link simbólico para o exe, eles vão voltar a localização do link não o exe real.

Assim, pode usar QueryFullProcessImageName de contornar isso:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;

internal static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, [Out]StringBuilder lpExeName, ref int lpdwSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    internal static extern IntPtr OpenProcess(
        UInt32 dwDesiredAccess,
        [MarshalAs(UnmanagedType.Bool)]
        Boolean bInheritHandle,
        Int32 dwProcessId
    );
}

public static class utils
{

    private const UInt32 PROCESS_QUERY_INFORMATION = 0x400;
    private const UInt32 PROCESS_VM_READ = 0x010;

    public static string getfolder()
    {
        Int32 pid = Process.GetCurrentProcess().Id;
        int capacity = 2000;
        StringBuilder sb = new StringBuilder(capacity);
        IntPtr proc;

        if ((proc = NativeMethods.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid)) == IntPtr.Zero)
            return "";

        NativeMethods.QueryFullProcessImageName(proc, 0, sb, ref capacity);

        string fullPath = sb.ToString(0, capacity);

        return Path.GetDirectoryName(fullPath) + @"\";
    }
}

Tente esta simples linha de código:

 string exePath = Path.GetDirectoryName( Application.ExecutablePath);

Outra solução é usar caminhos relativos apontando para o caminho de corrente:

Path.GetFullPath(".")

Eu não vi ninguém converter o LocalPath fornecido pela Net Núcleo reflexão em um caminho System.IO utilizável então aqui está a minha versão.

public static string GetApplicationRoot()
{
   var exePath = new Uri(System.Reflection.
   Assembly.GetExecutingAssembly().CodeBase).LocalPath;

   return new FileInfo(exePath).DirectoryName;

}

Isto irá devolver o "C: \ xxx \ xxx" caminho completo formatado para onde o seu código é.

Existem muitas maneiras de obter caminho executável, qual devemos usá-lo depende de nossas necessidades aqui é um link que discutir métodos diferentes.

Diferentes maneiras de obter aplicativo executável Path

Aqui está uma solução confiável que trabalha com 32 bits e 64 bits aplicações.

Adicionar estas referências:

using System.Diagnostics;

usando System.Management;

Adicione este método ao seu projeto:

public static string GetProcessPath(int processId)
{
    string MethodResult = "";
    try
    {
        string Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;

        using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query))
        {
            using (ManagementObjectCollection moc = mos.Get())
            {
                string ExecutablePath = (from mo in moc.Cast<ManagementObject>() select mo["ExecutablePath"]).First().ToString();

                MethodResult = ExecutablePath;

            }

        }

    }
    catch //(Exception ex)
    {
        //ex.HandleException();
    }
    return MethodResult;
}

Agora usá-lo assim:

int RootProcessId = Process.GetCurrentProcess().Id;

GetProcessPath(RootProcessId);

Observe que, se você conhece o id do processo, então este método retornará o ExecutePath correspondente.

extra, para os interessados:

Process.GetProcesses() 

... lhe dará uma matriz de todos os processos em execução, e ...

Process.GetCurrentProcess()

... lhe dará o processo atual, juntamente com suas informações, por exemplo, Id, etc, e também de controlo limitado por exemplo Matar, etc. *

Você pode criar um nome de pasta como recursos dentro do projeto usando Solution Explorer, em seguida, você pode colar um arquivo dentro dos recursos.

private void Form1_Load(object sender, EventArgs e) {
    string appName = Environment.CurrentDirectory;
    int l = appName.Length;
    int h = appName.LastIndexOf("bin");
    string ll = appName.Remove(h);                
    string g = ll + "Resources\\sample.txt";
    System.Diagnostics.Process.Start(g);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top