C# 如何获取应用程序';.NET控制台应用程序中的路径?

C# 如何获取应用程序';.NET控制台应用程序中的路径?,c#,.net,console,console-application,C#,.net,Console,Console Application,如何在控制台应用程序中找到应用程序的路径 在中,我可以使用Application.StartupPath查找当前路径,但这在控制台应用程序中似乎不可用。.1 如果您只需要目录,请将其与合并 AppDomain.CurrentDomain.BaseDirectory 1根据Mindor先生的评论: System.Reflection.Assembly.getExecutionGassembly().Location返回正在执行的程序集当前所在的位置,不执行时该位置可能在程序集所在的位置,也可能不

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

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

.1

如果您只需要目录,请将其与合并

AppDomain.CurrentDomain.BaseDirectory
1根据Mindor先生的评论:

System.Reflection.Assembly.getExecutionGassembly().Location
返回正在执行的程序集当前所在的位置,不执行时该位置可能在程序集所在的位置,也可能不在程序集所在的位置。对于卷影复制程序集,您将在临时目录中获得一个路径。将返回程序集的“永久”路径


您可能希望这样做:

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

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

AppDomain.CurrentDomain.BaseDirectory

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

Environment.GetCommandLineArgs()[0];
或更正确地获取目录路径:

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

Process.GetProcesses() 

不少人指出,
GetCommandLineArgs
不能保证返回程序名。看见这篇文章确实指出,“尽管很少有Windows程序使用这种怪癖(我自己也不知道有这样的怪癖)”。因此,可以“欺骗”GetCommandLineArgs,但我们讨论的是一个控制台应用程序。控制台应用程序通常是快速和肮脏的。因此,这符合我的KISS理念。

适用于任何对asp.net web应用感兴趣的人。下面是我对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应用程序。

您有两个选项可用于查找应用程序的目录,您可以根据自己的用途来选择

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

Assembly.GetEntryAssembly().Location
Assembly.getExecutionGassembly().Location

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

AppDomain.CurrentDomain.BaseDirectory
来自
GetEntryAssembly()
getExecutionGassembly()
的路径可以不同,即使在大多数情况下目录是相同的

<> > GeTeCyCy装配()/C> >您必须知道,如果条目模块是非托管的(即C++或VB6可执行文件),则可以返回<代码> null <代码>。在这些情况下,可以从Win32 API使用
GetModuleFileName

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

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

正如MSDN论坛帖子中所解释的,我使用了以下内容:

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

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

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

你可以用这个来代替

System.Environment.CurrentDirectory

如果要通过双击来调用exe,我会使用它

var thisPath = System.IO.Directory.GetCurrentDirectory();
我用过

System.AppDomain.CurrentDomain.BaseDirectory

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

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

System.IO.Directory.GetCurrentDirectory();
输出(在本地计算机上):

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

或者您可以尝试(最后还有一个反斜杠):

输出:

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


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

我的意思是,为什么不使用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());
                }
            }
    }
您可以像应用程序一样使用它。StartupPath:

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

My.Application.Info.DirectoryPath
适用于我(应用程序类型:类库)。不确定C#。。。
以字符串形式返回不带文件名的路径这里有一个可靠的解决方案,可用于32位和64位应用程序

添加以下参考:

使用系统诊断

使用制度管理

将此方法添加到项目中:

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;
}
请注意,如果您知道进程的id,那么此方法将返回相应的ExecutePath

对于感兴趣的人,额外提供:

Process.GetProcesses() 
…将为您提供当前运行的所有进程的数组,并且

Process.GetCurrentProcess()

…将为您提供当前流程及其信息,如Id等,以及有限控制,如Kill等。*

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


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

我使用了这段代码并得到了解决方案

AppDomain.CurrentDomain.BaseDirectory

这些方法都不能在特殊情况下工作,例如使用指向exe的符号链接,它们将返回链接的位置,而不是实际的exe

因此,我们可以使用以下方法:

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

尝试以下简单代码行:

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

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

System.AppContext.BaseDirectory
这是在.NET Framework 4.6和.NET Core1.0(以及.NET标准1.3)中引入的。请参阅:

根据,

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


我没有看到任何人将.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
格式化路径。

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

var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
上述解决方案在以下情况下正常工作:

  • 简单应用程序
  • 在另一个域中,Assembly.GetEntryAssembly()将返回null
  • DLL作为字节数组从嵌入式资源加载,并作为Assembly.Load(byteArrayOfEmbeddedDll)加载到AppDomain
  • 使用Mono的
    mkbundle
    bundle(其他方法不起作用)

获取可执行路径的方法有很多,我们应该使用哪种方法取决于我们的需要这里有一个链接
var appExePath = Process.GetCurrentProcess().MainModule.FileName;