首页 文章

如何在.NET控制台应用程序中获取应用程序的路径?

提问于
浏览
839

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

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

26 回答

  • 7

    我用过

    System.AppDomain.CurrentDomain.BaseDirectory
    

    当我想找到相对于应用程序文件夹的路径时 . 这适用于ASP.Net和winform应用程序 . 它也不需要任何对System.Web程序集的引用 .

  • 13

    如果您正在寻找兼容.NET Core的方法,请使用

    System.AppContext.BaseDirectory
    

    这是在.NET Framework 4.6和.NET Core 1.0(以及.NET Standard 1.3)中引入的 . 见:AppContext.BaseDirectory Property .

    根据this page

    这是.NET Core中AppDomain.CurrentDomain.BaseDirectory的首选替代品

  • 0

    有许多方法可以获得可执行路径,我们应该使用哪种方法取决于我们的需求,这里有一个讨论不同方法的链接 .

    Different ways to get Application Executable Path

  • 7

    我的意思是,为什么不是p / invoke方法?

    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());
                    }
                }
        }
    

    您可以像Application.StartupPath一样使用它:

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

    上面的答案是我所需要的90%,但是为我返回了一个Uri而不是常规路径 .

    正如MSDN论坛帖子How to convert URI path to normal filepath?中所解释的那样,我使用了以下内容:

    // Get normal filepath of this assembly's permanent directory
    var path = new Uri(
        System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
        ).LocalPath;
    
  • -1

    可能有点晚了,但值得一提:

    Environment.GetCommandLineArgs()[0];
    

    或者更正确地获取目录路径:

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

    Edit:

    不少人指出 GetCommandLineArgs 不保证返回程序名称 . 见The first word on the command line is the program name only by convention . 文章确实说明了"Although extremely few Windows programs use this quirk (I am not aware of any myself)" . 所以有可能'spoof' GetCommandLineArgs ,但我们正在谈论一个控制台应用程序 . 控制台应用程序通常很快且很脏 . 所以这符合我的KISS理念 .

  • 35
    AppDomain.CurrentDomain.BaseDirectory
    

    将解决问题以使用安装包引用第三方参考文件 .

  • 20

    试试这段简单的代码:

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

    以下行将为您提供一个应用程序路径:

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

    以上解决方案在以下情况下正常运行:

    • 简单的应用程序

    • 在另一个域中,Assembly.GetEntryAssembly()将返回null

    • DLL作为字节数组从嵌入式资源加载,并作为Assembly.Load(byteArrayOfEmbeddedDll)加载到AppDomain

  • 0

    这是一个可靠的解决方案,适用于 32bit64bit 应用程序 .

    添加以下参考:

    使用System.Diagnostics;使用System.Management;

    将此方法添加到您的项目:

    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;
    }
    

    现在使用它如下:

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

    请注意,如果您知道进程的id,那么此方法将返回相应的ExecutePath .

    Extra, for those interested:

    Process.GetProcesses()
    

    ...将为您提供所有当前正在运行的进程的数组,并...

    Process.GetCurrentProcess()
    

    ...将为您提供当前流程及其信息,例如Id等,并且还有限的控制,例如杀等等*

  • 3

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

    如果您想要的只是目录,请将其与System.IO.Path.GetDirectoryName相结合 .

    1根据Mr.Mindor的评论:System.Reflection.Assembly.GetExecutingAssembly() . Location返回执行程序集当前所在的位置,这可能是也可能不是程序集在不执行时所在的位置 . 对于卷影复制程序集,您将在临时目录中获取路径 . System.Reflection.Assembly.GetExecutingAssembly() . CodeBase将返回程序集的“永久”路径 .

  • 7

    这些方法都不能在特殊情况下工作,例如使用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) + @"\";
        }
    }
    
  • 8

    您有两种选择来查找应用程序的目录,您选择的目录取决于您的目的 .

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

    对于控制台应用程序,您可以尝试:

    System.IO.Directory.GetCurrentDirectory();
    

    输出(在我的本地机器上):

    c:\ users \ xxxxxxx \ documents \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug

    或者你可以尝试(最后还有一个额外的反斜杠):

    AppDomain.CurrentDomain.BaseDirectory
    

    输出:

    c:\ users \ xxxxxxx \ documents \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug \

  • 4

    您可以使用以下代码获取当前的应用程序目录 .

    AppDomain.CurrentDomain.BaseDirectory
    
  • 6

    Assembly.GetEntryAssembly().LocationAssembly.GetExecutingAssembly().Location

    System.IO.Path.GetDirectoryName() 结合使用仅获取目录 .

    GetEntryAssembly()GetExecutingAssembly() 的路径可以不同,即使大多数情况下目录也是相同的 .

    使用 GetEntryAssembly() 时,您必须注意,如果输入模块不受管理(即C或VB6可执行文件),则可以返回 null . 在这些情况下,可以使用Win32 API中的 GetModuleFileName

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
    
  • 373

    你可以使用这个 .

    System.Environment.CurrentDirectory
    
  • 130

    您可能希望这样做:

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

    您只需添加到项目引用 System.Windows.Forms ,然后像往常一样使用 System.Windows.Forms.Application.StartupPath .

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

  • 0

    如果应该通过双击调用exe来使用它

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

    您可以使用解决方案资源管理器在项目中创建文件夹名称作为资源,然后您可以在资源中粘贴文件 .

    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);
    }
    
  • 27

    我没有看到有人将.Net Core反射提供的LocalPath转换为可用的System.IO路径,所以这是我的版本 .

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

    这将返回完整的“C:\ xxx \ xxx”格式化代码所在的路径 .

  • -5

    我已经使用了这段代码并获得了解决方案 .

    AppDomain.CurrentDomain.BaseDirectory
    
  • 1055

    对于任何对asp.net网络应用感兴趣的人 . 以下是我对3种不同方法的结果

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

    结果

    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
    

    该应用程序从“C:\ inetpub \ SBSPortal_staging”物理运行,因此第一个解决方案绝对不适合Web应用程序 .

  • 18

    您可以使用以下代码,您将获得应用程序的完整路径:

    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();
        }
    }
    
  • 2

    在VB.net中

    My.Application.Info.DirectoryPath
    

    适合我(应用程序类型:类库) . 不确定C#...返回没有Filename的路径作为字符串

相关问题