如何在控制台应用程序中找到应用程序的路径?

在Windows窗体中,我可以使用应用程序。StartupPath来查找当前路径,但这在控制台应用程序中似乎不可用。


当前回答

我将此用于console + net 6

Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)

其他回答

试试下面这行简单的代码:

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

你可以简单地添加到你的项目引用System.Windows.Forms,然后像往常一样使用System.Windows.Forms. application . startuppath。

因此,不需要更复杂的方法或使用反射。

下面一行将给出应用程序路径:

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

上述解决方案在以下情况下正常工作:

简单的应用 在另一个域,Assembly.GetEntryAssembly()将返回null DLL以字节数组的形式从嵌入式资源加载,并以Assembly.Load的形式加载到AppDomain。 使用Mono的mkbundle bundles(没有其他方法工作)

您有两个选项来查找应用程序的目录,具体选择哪个取决于您的目的。

// 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);

这些方法在特殊情况下都不起作用,比如使用到exe的符号链接,它们将返回链接的位置,而不是实际的exe。

所以可以使用QueryFullProcessImageName来解决这个问题:

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) + @"\";
    }
}