Wie finde ich den Pfad der Anwendung in einer Konsolenanwendung?
In Windows Forms kann ich Application.StartupPath
verwenden, um den aktuellen Pfad zu finden, aber dies scheint in einer Konsolenanwendung nicht verfügbar zu sein.
System.Reflection.Assembly.GetExecutingAssembly()
. Location
1
Kombinieren Sie dies mit System.IO.Path.GetDirectoryName
, wenn Sie nur das Verzeichnis benötigen.
1 Gemäß dem Kommentar von Mr. Mindor:
System.Reflection.Assembly.GetExecutingAssembly().Location
gibt zurück, wo sich die ausführende Assembly gerade befindet. Möglicherweise befindet sich die Assembly dort, wo sie nicht ausgeführt wird. Beim Schattenkopieren von Assemblys erhalten Sie einen Pfad in einem temporären Verzeichnis.System.Reflection.Assembly.GetExecutingAssembly().CodeBase
gibt den 'permanenten' Pfad der Assembly zurück.
Mit dem folgenden Code können Sie das aktuelle Anwendungsverzeichnis abrufen.
AppDomain.CurrentDomain.BaseDirectory
Sie haben zwei Möglichkeiten, um das Verzeichnis der Anwendung zu finden, das Sie ausgewählt haben und das von Ihrem Verwendungszweck abhängt.
// 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);
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
nicht garantiert den Programmnamen zurückgibt. Siehe Das erste Wort in der Befehlszeile ist der Programmname nur nach Konvention . In dem Artikel heißt es: "Obwohl nur sehr wenige Windows-Programme diese Eigenart verwenden (mir ist selbst keine bekannt)". Es ist also möglich, GetCommandLineArgs
zu 'fälschen', 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 über "C:\inetpub\SBSPortal_staging" ausgeführt, sodass die erste Lösung definitiv nicht für Web-Apps geeignet ist.
Die obige Antwort entsprach zu 90% dem, was ich brauchte, lieferte mir jedoch einen Uri anstelle eines regulären Pfades zurück.
Wie im MSDN-Forenbeitrag erklärt, Wie konvertiere ich den URI-Pfad in einen normalen Dateipfad? , habe ich 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;
Möglicherweise möchten Sie dies tun:
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
sie können stattdessen dieses verwenden.
System.Environment.CurrentDirectory
Für Konsolenanwendungen können Sie Folgendes versuchen:
System.IO.Directory.GetCurrentDirectory();
Ausgabe (auf meinem lokalen Computer):
c:\users\xxxxxxx\documents\visual studio 2012\Projects\ImageHandler\GetDir\bin\Debug
Oder Sie können es versuchen (am Ende gibt es einen zusätzlichen Backslash):
AppDomain.CurrentDomain.BaseDirectory
Ausgabe:
c:\users\xxxxxxx\documents\visual studio 2012\Projects\ImageHandler\GetDir\bin\Debug \
Ich habe diesen Code verwendet und die Lösung erhalten.
AppDomain.CurrentDomain.BaseDirectory
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 .
Nach diese Seite ,
Dies ist der bevorzugte Ersatz für AppDomain.CurrentDomain.BaseDirectory in .NET Core
Sie können Ihren Projektreferenzen einfach System.Windows.Forms
hinzufügen und dann System.Windows.Forms.Application.StartupPath
wie gewohnt verwenden.
Es sind also keine komplizierteren Methoden oder die Verwendung der Reflexion erforderlich.
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 benutze dies, wenn die exe durch Doppelklick aufgerufen werden soll
var thisPath = System.IO.Directory.GetCurrentDirectory();
Ich meine, warum nicht eine p/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 genauso verwenden wie Application.StartupPath:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
Die folgende Zeile gibt Ihnen einen Anwendungspfad:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
Die oben genannte Lösung funktioniert in den folgenden Situationen ordnungsgemäß:
mkbundle
Bundles (keine anderen Methoden funktionieren)in VB.net
My.Application.Info.DirectoryPath
funktioniert bei mir (Anwendungstyp: Klassenbibliothek). Nicht sicher in Bezug auf C # ... Gibt den Pfad ohne Dateinamen als Zeichenfolge zurück
Assembly.GetEntryAssembly().Location
oder Assembly.GetExecutingAssembly().Location
Verwenden Sie in Kombination mit System.IO.Path.GetDirectoryName()
, um nur das Verzeichnis abzurufen.
Die Pfade von GetEntryAssembly()
und GetExecutingAssembly()
können unterschiedlich sein, auch wenn das Verzeichnis in den meisten Fällen identisch ist.
Mit GetEntryAssembly()
müssen Sie sich darüber im Klaren sein, dass dies null
zurückgeben kann, wenn das Eingabemodul nicht verwaltet wird (dh C++ oder VB6 ausführbar). In diesen Fällen ist es möglich, GetModuleFileName
über die Win32-API 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.
Versuchen Sie diese einfache Codezeile:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
Keine dieser Methoden funktioniert in besonderen Fällen wie der Verwendung eines symbolischen Links zur exe. Sie geben den Ort des Links zurück, nicht die tatsächliche exe.
Verwenden Sie also QueryFullProcessImageName , 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) + @"\";
}
}
Eine andere Lösung verwendet relative Pfade, die auf den aktuellen Pfad verweisen:
Path.GetFullPath(".")
Sie können folgenden Code verwenden, Sie erhalten den vollständigen Pfad der Anwendung:
class Program
{
static void Main(string[] args)
{
string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
WriteLine($"ApplicationPath ---{AppPath}");
//OutPut// //ApplicationPath---C:\Users\TestUser\source\repos\ThreadStack\ThreadStack\bin\Debug\ThreadStack.exe
ReadLine();
}
}
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 Methoden zum Abrufen des ausführbaren Anwendungspfads
Ich habe niemanden gesehen, der LocalPath von .Net Core Reflection in einen verwendbaren System.IO-Pfad konvertiert hat. Hier ist also meine Version.
public static string GetApplicationRoot()
{
var exePath = new Uri(System.Reflection.
Assembly.GetExecutingAssembly().CodeBase).LocalPath;
return new FileInfo(exePath).DirectoryName;
}
Das wird den vollständigen "C:\xxx\xxx" formatierten Pfad zu Ihrem Code zurückgeben.