如何在控制台应用程序中找到应用程序的路径?
在Windows Forms中,我可以使用它Application.StartupPath
来找到当前路径,但这似乎在控制台应用程序中不可用。
如何在控制台应用程序中找到应用程序的路径?
在Windows Forms中,我可以使用它Application.StartupPath
来找到当前路径,但这似乎在控制台应用程序中不可用。
Answers:
System.Reflection.Assembly.GetExecutingAssembly()
。1个Location
System.IO.Path.GetDirectoryName
如果只需要目录,则将其与。
1 根据Mindor先生的评论:
System.Reflection.Assembly.GetExecutingAssembly().Location
返回正在执行的程序集的当前位置,不执行时可能会或可能不在该程序集的位置。对于卷影复制程序集,您将在temp目录中获得一个路径。System.Reflection.Assembly.GetExecutingAssembly().CodeBase
将返回程序集的“永久”路径。
GetExecutingAssembly
返回包含当前正在执行的代码的程序集。不一定是控制台.exe程序集。它可能是从完全不同的位置加载的装配体。您将不得不使用GetEntryAssembly
!另请注意,CodeBase
当程序集位于GAC中时,可能未设置。更好的选择是AppDomain.CurrentDomain.BaseDirectory
。
您可以使用以下代码来获取当前应用程序目录。
AppDomain.CurrentDomain.BaseDirectory
BaseDirectory
可以在运行时设置?它只有一个吸气剂。
您可以通过两个选项来查找应用程序的目录,具体取决于您的用途。
// 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);
var localDirectory = new Uri(directory).LocalPath;
可能有点晚了,但这值得一提:
Environment.GetCommandLineArgs()[0];
或者更正确地获取目录路径:
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
编辑:
不少人指出,GetCommandLineArgs
不能保证返回程序名称。请参阅命令行上的第一个单词仅是约定的程序名称。这篇文章确实指出“尽管很少有Windows程序使用此怪癖(我自己都不知道)”。因此可以“欺骗” GetCommandLineArgs
,但我们正在谈论控制台应用程序。控制台应用程序通常又快又脏。因此,这符合我的KISS哲学。
对于对asp.net Web应用程序感兴趣的任何人。这是我三种不同方法的结果
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应用程序。
上面的答案是我需要的90%,但是为我返回了Uri而不是常规路径。
如MSDN论坛帖子中所述,如何将URI路径转换为普通文件路径?,我使用了以下内容:
// Get normal filepath of this assembly's permanent directory
var path = new Uri(
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
).LocalPath;
File.CreateDirectory(path)
,否则它将为您提供一个例外,即它不允许URI路径...
#
字符)的路径不起作用。标识符及其后的所有内容将从结果路径中截断。
new Uri
和System.IO.Path.GetDirectoryName
?这将为您提供一个普通的路径字符串,而不是一个Uri
。
您可以改用这个。
System.Environment.CurrentDirectory
如果您正在寻找与.NET Core兼容的方式,请使用
System.AppContext.BaseDirectory
.NET Framework 4.6和.NET Core 1.0(和.NET Standard 1.3)中对此进行了介绍。请参阅:AppContext.BaseDirectory属性。
根据此页面,
这是.NET Core中AppDomain.CurrentDomain.BaseDirectory的首选替代品
Process.GetCurrentProcess().MainModule.FileName
对于控制台应用程序,您可以尝试以下操作:
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 \
BaseDirectory
可以在运行时设置。不保证是正确的”
我已使用此代码并获得了解决方案。
AppDomain.CurrentDomain.BaseDirectory
您可以简单地添加到项目引用中System.Windows.Forms
,然后System.Windows.Forms.Application.StartupPath
照常使用。
因此,不需要更复杂的方法或使用反射。
下一行将为您提供一个应用程序路径:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
上述解决方案在以下情况下正常工作:
mkbundle
捆绑包(其他方法无效)我的意思是,为什么不使用ap / 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");
Assembly.GetEntryAssembly().Location
要么 Assembly.GetExecutingAssembly().Location
与组合使用System.IO.Path.GetDirectoryName()
仅获取目录。
尽管大多数情况下目录是相同的,但来自GetEntryAssembly()
和的路径GetExecutingAssembly()
可以不同。
随着GetEntryAssembly()
你要知道,这可以返回null
,如果输入模块未被管理(即C ++或VB6可执行文件)。在这种情况下,可以使用GetModuleFileName
Win32 API:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
这些方法在特殊情况下均无法使用,例如使用指向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) + @"\";
}
}
尝试以下简单的代码行:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
我没有看到任何人将.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”格式的路径返回到您的代码所在的位置。
获取可执行路径的方法有很多,我们应该使用哪种方法取决于我们的需求。这里是一个讨论不同方法的链接。
这是可与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等)以及有限的控制权(例如Kill等)*
您可以使用解决方案资源管理器在项目中将文件夹名称创建为资源,然后将文件粘贴到资源中。
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);
}