Como encontro o caminho do aplicativo em um aplicativo de console?
No Windows Forms , posso usar Application.StartupPath
para encontrar o caminho atual, mas isso não parece estar disponível em um aplicativo de console.
Como encontro o caminho do aplicativo em um aplicativo de console?
No Windows Forms , posso usar Application.StartupPath
para encontrar o caminho atual, mas isso não parece estar disponível em um aplicativo de console.
Respostas:
System.Reflection.Assembly.GetExecutingAssembly()
. 1Location
Combine isso com System.IO.Path.GetDirectoryName
se tudo o que você deseja é o diretório.
1 Conforme o comentário do Sr.Mindor:
System.Reflection.Assembly.GetExecutingAssembly().Location
retorna onde a montagem executora está atualmente localizada, que pode ou não estar onde a montagem está localizada quando não está sendo executada. 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 montagem.
GetExecutingAssembly
retorna assembly que contém o código que está sendo executado no momento . Isso pode não ser necessariamente o assembly .exe do console . Pode ser uma montagem que foi carregada de um local totalmente diferente. Você terá que usar GetEntryAssembly
! Observe também que CodeBase
pode não ser definido quando a montagem está no GAC. A melhor alternativa é AppDomain.CurrentDomain.BaseDirectory
.
Você pode usar o código a seguir para obter o diretório atual do aplicativo.
AppDomain.CurrentDomain.BaseDirectory
BaseDirectory
pode ser definido em tempo de execução? Só tem um getter.
Você tem duas opções para encontrar o diretório do aplicativo, que você escolher dependerá do seu objetivo.
// 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);
var localDirectory = new Uri(directory).LocalPath;
Provavelmente um pouco tarde, 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:
Muitas pessoas apontaram que GetCommandLineArgs
não é garantido o retorno do nome do programa. Consulte A primeira palavra na linha de comando é o nome do programa apenas por convenção . O artigo afirma que "Embora extremamente poucos programas do Windows usem essa peculiaridade (eu não conheço nenhum deles)". Portanto, é possível 'falsificar' GetCommandLineArgs
, mas estamos falando de um aplicativo de console. Aplicativos de console geralmente são rápidos e sujos. Então isso se encaixa na minha filosofia do KISS.
Para qualquer pessoa interessada 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 em "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 retornou um Uri em vez de um caminho regular para mim.
Conforme explicado na postagem dos fóruns do MSDN, como converter o caminho do URI em caminho de arquivo normal? , 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;
File.CreateDirectory(path)
, ele vai te dar a ressalva de que ele não permite caminhos URI ...
#
caractere). O identificador e tudo o que segue são truncados do caminho resultante.
new Uri
e System.IO.Path.GetDirectoryName
? Isso fornece uma string de caminho normal em vez de a Uri
.
você pode usar este aqui.
System.Environment.CurrentDirectory
Se você estiver procurando uma maneira compatível com o .NET Core, use
System.AppContext.BaseDirectory
Isso foi introduzido no .NET Framework 4.6 e .NET Core 1.0 (e .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
Process.GetCurrentProcess().MainModule.FileName
Para aplicativos de console, você pode tentar o seguinte:
System.IO.Directory.GetCurrentDirectory();
Saída (na minha máquina local):
c: \ users \ xxxxxxx \ documents \ visual studio 2012 \ Projetos \ ImageHandler \ GetDir \ bin \ Debug
Ou você pode tentar (há uma barra invertida adicional no final):
AppDomain.CurrentDomain.BaseDirectory
Resultado:
c: \ users \ xxxxxxx \ documents \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug \
BaseDirectory
pode ser definido em tempo de execução. NÃO é garantido que esteja correto"
Eu usei esse código e obtenha a solução.
AppDomain.CurrentDomain.BaseDirectory
Você pode simplesmente adicionar às referências do seu projeto System.Windows.Forms
e usar oSystem.Windows.Forms.Application.StartupPath
normalmente.
Portanto, não é necessário métodos mais complicados ou usar a reflexão.
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:
mkbundle
pacotes configuráveis do Mono (nenhum outro método funciona)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 eu quero encontrar um caminho relativo a uma pasta de aplicativos. Isso funciona para aplicativos ASP.Net e winform. Também não requer nenhuma referência aos assemblies System.Web.
Quero dizer, por que 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ê o usaria como o Application.StartupPath:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
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()
eGetExecutingAssembly()
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 voltar null
se o módulo de entrada é não gerenciado (ou seja, C ++ ou executável VB6). Nesses casos, é possível usar a GetModuleFileName
partir 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 consultar os arquivos de referência de terceiros com pacotes de instalação.
Nenhum desses métodos funciona em casos especiais, como o uso de um link simbólico para o exe; eles retornarão a localização do link e não o exe real.
Portanto, 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 simples linha de código:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
Outra solução é usar caminhos relativos que apontam para o caminho atual:
Path.GetFullPath(".")
Não vi ninguém converter o LocalPath fornecido pelo .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 está o seu código.
Existem muitas maneiras de obter o caminho executável, e qual deles devemos usar depende de nossas necessidades. Aqui está um link que discute métodos diferentes.
Maneiras diferentes de obter o caminho executável do aplicativo
Aqui está uma solução confiável que funciona com 32 bits e 64 bits aplicativos de .
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<ManagementObject>() select mo["ExecutablePath"]).First().ToString();
MethodResult = ExecutablePath;
}
}
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
Agora use-o 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()
... fornecerá uma matriz de todos os processos em execução no momento e ...
Process.GetCurrentProcess()
... fornecerá o processo atual, juntamente com suas informações, por exemplo, ID, etc., e também controle limitado, por exemplo, Kill, etc. *
Você pode criar um nome de pasta como Recursos no projeto usando o Gerenciador de Soluções e 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);
}