Como posso obter o caminho do aplicativo em um aplicativo de console do .NET?

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

No Windows Forms , eu posso usar Application.StartupPath para encontrar o caminho atual, mas isso não parece estar disponível em um aplicativo de console.

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

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

1 De acordo com o comentário do Sr. Mindor:
System.Reflection.Assembly.GetExecutingAssembly().Location retorna onde o assembly em execução está localizado no momento, que pode ou não estar onde o assembly está localizado quando não está em execução. No caso de montagens de cópia de sombra, você obterá um caminho em um diretório temporário. System.Reflection.Assembly.GetExecutingAssembly().CodeBase retornará o caminho ‘permanente’ da assembly.

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

 AppDomain.CurrentDomain.BaseDirectory 

Você tem duas opções para encontrar o diretório do aplicativo, que você escolheu 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 atrasado, mas vale a pena mencionar:

 Environment.GetCommandLineArgs()[0]; 

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

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

Editar:

Algumas pessoas apontaram que não é garantido que GetCommandLineArgs retorne o nome do programa. Veja A primeira palavra na linha de comando é o nome do programa apenas por convenção . O artigo afirma que “Embora muito poucos programas do Windows usem essa peculiaridade (não estou ciente de nenhum eu mesmo)”. Portanto, é possível ‘spoof’ GetCommandLineArgs , mas estamos falando de um aplicativo de console. Aplicativos de console geralmente são rápidos e sujos. Então isso se encheckbox com a minha filosofia KISS.

Para qualquer pessoa interessada em aplicativos da web asp.net. Aqui estão os meus resultados de 3 methods 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 a partir de “C: \ inetpub \ SBSPortal_staging”, portanto, a primeira solução definitivamente não é apropriada para aplicativos da web.

A resposta acima foi de 90% do que eu precisava, mas retornei um Uri ao invés de um caminho regular para mim.

Como explicado no post de fóruns do MSDN, Como converter o caminho do URI para o caminho de arquivo normal? 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 fazer isso:

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

você pode usar este em vez disso.

 System.Environment.CurrentDirectory 

Para aplicativos de console, você pode tentar isso:

 System.IO.Directory.GetCurrentDirectory(); 

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

c: \ users \ xxxxxxx \ documentos \ visual studio 2012 \ Projetos \ ImageHandler \ GetDir \ bin \ Debug

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

 AppDomain.CurrentDomain.BaseDirectory 

Saída:

c: \ users \ xxxxxxx \ documentos \ visual studio 2012 \ Projetos \ ImageHandler \ GetDir \ bin \ Debug \

Eu usei este código e obtenha a solução.

 AppDomain.CurrentDomain.BaseDirectory 

Eu uso isso se o exe deve ser chamado clicando duas vezes nele

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

Eu tenho usado

 System.AppDomain.CurrentDomain.BaseDirectory 

quando quero encontrar um caminho relativo a uma pasta de aplicativos. Isso funciona para aplicativos ASP.Net e winform. Também não requer qualquer referência a assemblies System.Web.

Você pode simplesmente adicionar ao seu projeto referências System.Windows.Forms e, em seguida, use o System.Windows.Forms.Application.StartupPath como de costume.

Então, não precisa de methods mais complicados ou usando o reflexo.

Quero dizer, porque não ap / invocar 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ê iria usá-lo apenas como o Application.StartupPath:

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

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

 System.AppContext.BaseDirectory 

Isso foi introduzido no .NET Framework 4.6 e no .NET Core 1.0 (e no .NET Standard 1.3). Consulte: Propriedade AppContext.BaseDirectory .

De acordo com esta página ,

Este é o substituto preferido para AppDomain.CurrentDomain.BaseDirectory no .NET Core

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() podem ser diferentes, embora na maioria dos casos o diretório seja o mesmo.

Com GetEntryAssembly() você tem que estar ciente de que isso pode retornar null se o módulo de input não for gerenciado (ou seja, executável C ++ ou VB6). Nesses casos, é possível usar GetModuleFileName da API do 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 referenciar os arquivos de referência de terceiros com pacotes de instalação.

Nenhum desses methods funciona em casos especiais como o uso de um link simbólico para o exe, eles retornarão a localização do link não o exe real.

Então, pode usar QueryFullProcessImageName para 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) + @"\"; } } 

Experimente esta linha simples de código:

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

em VB.net

 My.Application.Info.DirectoryPath 

funciona para mim (tipo de aplicativo: biblioteca de classs). Não tenho certeza sobre C # … Retorna o caminho sem o nome do arquivo como string

Eu não vi ninguém converter o LocalPath fornecido pelo reflexo do .Net Core em um caminho System.IO utilizável, então aqui está minha versão.

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

Isso retornará o caminho formatado “C: \ xxx \ xxx” completo para onde seu código está.

A linha a seguir fornecerá um caminho de aplicativo:

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

A solução acima está funcionando corretamente nas seguintes situações:

  • aplicativo simples
  • em outro domínio onde Assembly.GetEntryAssembly () retornaria null
  • DLL é carregada de resources incorporados como matriz de bytes e carregada para AppDomain como Assembly.Load (byteArrayOfEmbeddedDll)

Há muitas maneiras de obter o caminho do executável, o qual devemos usá-lo depende de nossas necessidades, aqui está um link que discute methods diferentes.

Diferentes maneiras de obter o caminho do executável do aplicativo

Aqui está uma solução confiável que funciona com aplicativos de 32 e 64 bits .

Adicione estas referências:

using System.Diagnostics;

using 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() select mo["ExecutablePath"]).First().ToString(); MethodResult = ExecutablePath; } } } catch //(Exception ex) { //ex.HandleException(); } return MethodResult; } 

Agora use assim:

 int RootProcessId = Process.GetCurrentProcess().Id; GetProcessPath(RootProcessId); 

Observe que, se você souber o id do processo, esse método retornará o ExecutePath correspondente.

Extra, para os interessados:

 Process.GetProcesses() 

… lhe dará uma matriz de todos os processos atualmente em execução e …

 Process.GetCurrentProcess() 

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

Você pode criar um nome de pasta como Recursos no projeto usando o Solution Explorer e, em seguida, pode colar um arquivo nos 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); }