Wie finde ich den Pfad der Anwendung in einer Konsolenanwendung?
In Windows Forms kann ich Application.StartupPath
den aktuellen Pfad suchen, dies scheint jedoch in einer Konsolenanwendung nicht verfügbar zu sein.
Wie finde ich den Pfad der Anwendung in einer Konsolenanwendung?
In Windows Forms kann ich Application.StartupPath
den aktuellen Pfad suchen, dies scheint jedoch in einer Konsolenanwendung nicht verfügbar zu sein.
Antworten:
System.Reflection.Assembly.GetExecutingAssembly()
. 1Location
Kombinieren Sie das mit, System.IO.Path.GetDirectoryName
wenn Sie nur das Verzeichnis wollen.
1 Gemäß dem Kommentar von Mr.Mindor: Gibt
System.Reflection.Assembly.GetExecutingAssembly().Location
zurück, wo sich die ausführende Assembly befindet, die sich möglicherweise dort befindet, wo sich die Assembly befindet, wenn sie nicht ausgeführt wird. Im Fall von Schattenkopier-Assemblys erhalten Sie einen Pfad in einem temporären Verzeichnis.System.Reflection.Assembly.GetExecutingAssembly().CodeBase
gibt den 'permanenten' Pfad der Assembly zurück.
GetExecutingAssembly
Gibt eine Assembly zurück, die den aktuell ausgeführten Code enthält . Dies muss nicht unbedingt die .exe- Assembly der Konsole sein . Es kann sich um eine Baugruppe handeln, die von einem völlig anderen Ort geladen wurde. Sie müssen verwenden GetEntryAssembly
! Beachten Sie auch, dass dies CodeBase
möglicherweise nicht festgelegt wird, wenn sich die Baugruppe im GAC befindet. Die bessere Alternative ist AppDomain.CurrentDomain.BaseDirectory
.
Mit dem folgenden Code können Sie das aktuelle Anwendungsverzeichnis abrufen.
AppDomain.CurrentDomain.BaseDirectory
BaseDirectory
dies zur Laufzeit eingestellt werden kann? Es hat nur einen Getter.
Sie haben zwei Möglichkeiten, um das Verzeichnis der Anwendung zu finden, das Sie je nach Verwendungszweck auswählen.
// 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;
Wahrscheinlich etwas spät, aber das ist eine Erwähnung wert:
Environment.GetCommandLineArgs()[0];
Oder genauer gesagt, um nur den Verzeichnispfad zu erhalten:
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
Bearbeiten:
Nicht wenige Leute haben darauf hingewiesen, dass GetCommandLineArgs
die Rückgabe des Programmnamens nicht garantiert ist. Siehe Das erste Wort in der Befehlszeile ist der Programmname nur gemäß Konvention . In dem Artikel heißt es: "Obwohl extrem wenige Windows-Programme diese Eigenart verwenden (mir sind keine bekannt)." Es ist also möglich, zu "fälschen" GetCommandLineArgs
, aber es handelt sich um eine Konsolenanwendung. Konsolen-Apps sind normalerweise schnell und schmutzig. Das passt also zu meiner KISS-Philosophie.
Für alle, die sich für asp.net Web Apps interessieren. Hier sind meine Ergebnisse von 3 verschiedenen Methoden
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);
}
Ergebnis
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
Die App wird physisch von "C: \ inetpub \ SBSPortal_staging" ausgeführt, sodass die erste Lösung definitiv nicht für Web-Apps geeignet ist.
Die Antwort oben war 90% von dem, was ich brauchte, gab aber einen Uri anstelle eines regulären Pfades für mich zurück.
Wie im Beitrag in den MSDN-Foren erläutert , konvertieren Sie den URI-Pfad in einen normalen Dateipfad. Ich habe folgendes verwendet:
// 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)
, gibt es Ihnen die Ausnahme, dass es keine URI-Pfade erlaubt ...
#
Zeichen) enthalten. Der Bezeichner und alles, was darauf folgt, wird vom resultierenden Pfad abgeschnitten.
new Uri
und System.IO.Path.GetDirectoryName
? Das gibt Ihnen eine normale Pfadzeichenfolge anstelle von a Uri
.
Sie können stattdessen diesen verwenden.
System.Environment.CurrentDirectory
Wenn Sie nach einer .NET Core-kompatiblen Methode suchen, verwenden Sie
System.AppContext.BaseDirectory
Dies wurde in .NET Framework 4.6 und .NET Core 1.0 (und .NET Standard 1.3) eingeführt. Siehe: AppContext.BaseDirectory-Eigenschaft .
Laut dieser Seite ,
Dies ist der bevorzugte Ersatz für AppDomain.CurrentDomain.BaseDirectory in .NET Core
Process.GetCurrentProcess().MainModule.FileName
Für Konsolenanwendungen können Sie Folgendes versuchen:
System.IO.Directory.GetCurrentDirectory();
Ausgabe (auf meinem lokalen Computer):
c: \ Benutzer \ xxxxxxx \ Dokumente \ Visual Studio 2012 \ Projekte \ ImageHandler \ GetDir \ bin \ Debug
Oder Sie können es versuchen (am Ende gibt es einen zusätzlichen Backslash):
AppDomain.CurrentDomain.BaseDirectory
Ausgabe:
c: \ Benutzer \ xxxxxxx \ Dokumente \ Visual Studio 2012 \ Projekte \ ImageHandler \ GetDir \ bin \ Debug \
BaseDirectory
kann zur Laufzeit eingestellt werden. Es ist NICHT garantiert, dass es korrekt ist"
Ich habe diesen Code verwendet und die Lösung erhalten.
AppDomain.CurrentDomain.BaseDirectory
Sie können einfach zu Ihren Projektreferenzen hinzufügen System.Windows.Forms
und diese dann System.Windows.Forms.Application.StartupPath
wie gewohnt verwenden.
Sie brauchen also keine komplizierteren Methoden oder die Verwendung der Reflexion.
In der folgenden Zeile erhalten Sie einen Anwendungspfad:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
Die obige Lösung funktioniert in den folgenden Situationen ordnungsgemäß:
mkbundle
Bundles (keine anderen Methoden funktionieren)Ich benutze dies, wenn die Exe durch Doppelklick aufgerufen werden soll
var thisPath = System.IO.Directory.GetCurrentDirectory();
Ich habe benutzt
System.AppDomain.CurrentDomain.BaseDirectory
wenn ich einen Pfad relativ zu einem Anwendungsordner finden möchte. Dies funktioniert sowohl für ASP.Net- als auch für Winform-Anwendungen. Es ist auch kein Verweis auf System.Web-Assemblys erforderlich.
Ich meine, warum nicht ap / invoke Methode?
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());
}
}
}
Sie würden es genau wie Application.StartupPath verwenden:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
Assembly.GetEntryAssembly().Location
oder Assembly.GetExecutingAssembly().Location
In Kombination mit verwenden System.IO.Path.GetDirectoryName()
, um nur das Verzeichnis abzurufen.
Die Pfade von GetEntryAssembly()
und GetExecutingAssembly()
können unterschiedlich sein, obwohl das Verzeichnis in den meisten Fällen dasselbe ist.
Mit GetEntryAssembly()
Ihnen bewusst sein, dass diese zurückgeben kann , null
wenn das Eingabemodul unmanaged ist (dh C ++ oder VB6 ausführbar). In diesen Fällen ist es möglich, GetModuleFileName
über die Win32-API Folgendes zu verwenden:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
AppDomain.CurrentDomain.BaseDirectory
Behebt das Problem, indem auf Referenzdateien von Drittanbietern mit Installationspaketen verwiesen wird.
Keine dieser Methoden funktioniert in besonderen Fällen wie der Verwendung eines symbolischen Links zur Exe. Sie geben den Speicherort des Links zurück, nicht die tatsächliche Exe.
Sie können also QueryFullProcessImageName verwenden , um dies zu umgehen :
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) + @"\";
}
}
Versuchen Sie diese einfache Codezeile:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
Eine andere Lösung besteht darin, relative Pfade zu verwenden, die auf den aktuellen Pfad zeigen:
Path.GetFullPath(".")
Ich habe niemanden gesehen, der den von .Net Core Reflection bereitgestellten LocalPath in einen verwendbaren System.IO-Pfad konvertiert hat. Hier ist meine Version.
public static string GetApplicationRoot()
{
var exePath = new Uri(System.Reflection.
Assembly.GetExecutingAssembly().CodeBase).LocalPath;
return new FileInfo(exePath).DirectoryName;
}
Dadurch wird der vollständig mit "C: \ xxx \ xxx" formatierte Pfad zu Ihrem Code zurückgegeben.
Es gibt viele Möglichkeiten, einen ausführbaren Pfad zu erhalten. Welchen Pfad wir verwenden sollten, hängt von unseren Anforderungen ab. Hier finden Sie einen Link, in dem verschiedene Methoden erläutert werden.
Verschiedene Möglichkeiten, um den ausführbaren Pfad der Anwendung abzurufen
Hier ist eine zuverlässige Lösung, die mit 32bit und 64bit funktioniert Anwendungen .
Fügen Sie diese Referenzen hinzu:
using System.Diagnostics;
using System.Management;
Fügen Sie diese Methode Ihrem Projekt hinzu:
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;
}
Verwenden Sie es jetzt so:
int RootProcessId = Process.GetCurrentProcess().Id;
GetProcessPath(RootProcessId);
Beachten Sie, dass diese Methode den entsprechenden ExecutePath zurückgibt, wenn Sie die ID des Prozesses kennen.
Extra für Interessierte:
Process.GetProcesses()
... gibt Ihnen eine Reihe aller aktuell ausgeführten Prozesse und ...
Process.GetCurrentProcess()
... gibt Ihnen den aktuellen Prozess zusammen mit ihren Informationen, z. B. ID usw. und auch eingeschränkter Kontrolle, z. B. Töten usw. *
Sie können mit dem Projektmappen-Explorer einen Ordnernamen als Ressourcen im Projekt erstellen und anschließend eine Datei in die Ressourcen einfügen.
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);
}