如何在控制台应用程序中找到应用程序的路径?
在Windows窗体中,我可以使用应用程序。StartupPath来查找当前路径,但这在控制台应用程序中似乎不可用。
如何在控制台应用程序中找到应用程序的路径?
在Windows窗体中,我可以使用应用程序。StartupPath来查找当前路径,但这在控制台应用程序中似乎不可用。
当前回答
这些方法在特殊情况下都不起作用,比如使用到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) + @"\";
}
}
其他回答
可能有点晚了,但这个值得提一下:
Environment.GetCommandLineArgs()[0];
或者更准确地获取目录路径:
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
编辑:
相当多的人已经指出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应用程序。
这里有一个可靠的解决方案,适用于32位和64位应用程序。
添加以下参考:
使用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。
有兴趣的同学可以额外订阅:
Process.GetProcesses()
...将为您提供当前运行的所有进程的数组,并且…
Process.GetCurrentProcess()
...会给你当前的进程,以及他们的信息,如Id等,也有限制控制,如杀死等*
试试下面这行简单的代码:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
你可以简单地添加到你的项目引用System.Windows.Forms,然后像往常一样使用System.Windows.Forms. application . startuppath。
因此,不需要更复杂的方法或使用反射。