콘솔 응용 프로그램에서 응용 프로그램의 경로를 어떻게 찾습니까?
에서 윈도우 폼 , 내가 사용할 수있는 Application.StartupPath
현재 경로를 찾을 수 있지만, 이것은 콘솔 응용 프로그램에서 사용할 수하지 않는 것 같습니다.
콘솔 응용 프로그램에서 응용 프로그램의 경로를 어떻게 찾습니까?
에서 윈도우 폼 , 내가 사용할 수있는 Application.StartupPath
현재 경로를 찾을 수 있지만, 이것은 콘솔 응용 프로그램에서 사용할 수하지 않는 것 같습니다.
답변:
System.Reflection.Assembly.GetExecutingAssembly()
. 1Location
System.IO.Path.GetDirectoryName
원하는 것이 디렉토리이면 결합 하십시오.
1 Mr.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 웹앱에 관심이있는 사람 다음은 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"에서 실행 중이므로 첫 번째 솔루션은 웹 앱에는 적합하지 않습니다.
위의 답변은 내가 필요한 것의 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
? 그러면 a 대신 일반 경로 문자열이 제공됩니다 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 : \ 사용자 \ xxxxxxx \ documents \ visual studio 2012 \ 프로젝트 \ ImageHandler \ GetDir \ bin \ Debug \
BaseDirectory
런타임에서 설정할 수 있습니다. 정확하지는 않습니다"
이 코드를 사용하여 솔루션을 얻었습니다.
AppDomain.CurrentDomain.BaseDirectory
프로젝트 참조에 추가 System.Windows.Forms
한 다음 System.Windows.Forms.Application.StartupPath
평소 와 같이 사용할 수 있습니다 .
따라서 더 복잡한 방법이나 반사를 사용할 필요가 없습니다.
exe를 두 번 클릭하여 호출 해야하는 경우 이것을 사용합니다.
var thisPath = System.IO.Directory.GetCurrentDirectory();
나는 사용했다
System.AppDomain.CurrentDomain.BaseDirectory
응용 프로그램 폴더와 관련된 경로를 찾고 싶을 때. 이것은 ASP.Net 및 winform 응용 프로그램 모두에서 작동합니다. 또한 System.Web 어셈블리에 대한 참조가 필요하지 않습니다.
다음 줄은 응용 프로그램 경로를 제공합니다.
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) + @"\";
}
}
.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) 및 제한된 제어 (예 : 킬 등)를 제공합니다. *
솔루션 탐색기를 사용하여 프로젝트 내에서 폴더 이름을 리소스로 생성 한 다음 리소스 내에 파일을 붙여 넣을 수 있습니다.
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);
}