에서 응용 프로그램의 경로를 가져오려면 어떻게 해야 합니까?NET 콘솔 애플리케이션?
콘솔 응용 프로그램에서 응용 프로그램의 경로를 찾으려면 어떻게 해야 합니까?
Windows Forms에서 사용할 수 있는 기능Application.StartupPath
현재 경로를 찾지만 콘솔 응용 프로그램에서는 사용할 수 없는 것 같습니다.
System.Reflection.Assembly.GetExecutingAssembly()
.Location
1
디렉토리만 원하는 경우 이를 와 결합합니다.
1Mindor씨의 논평에 따르면:
System.Reflection.Assembly.GetExecutingAssembly().Location
실행 중인 어셈블리가 현재 있는 위치를 반환합니다. 이 위치는 실행 중이지 않을 때 어셈블리가 있는 위치일 수도 있고 아닐 수도 있습니다.섀도 복사 어셈블리의 경우 임시 디렉터리의 경로를 얻을 수 있습니다. 어셈블리의 '영구적' 경로를 반환합니다.
다음 코드를 사용하여 현재 응용 프로그램 디렉터리를 가져올 수 있습니다.
AppDomain.CurrentDomain.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);
조금 늦었을 수도 있지만, 이것은 언급할 가치가 있습니다.
Environment.GetCommandLineArgs()[0];
또는 디렉터리 경로만 가져오는 것이 더 정확합니다.
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
편집:
이 그것을 지적했습니다.GetCommandLineArgs
프로그램 이름을 반환하는 것이 보장되지 않습니다.참고 항목명령줄의 첫 번째 단어는 규약에 의한 프로그램 이름입니다.이 문서에는 "극소수의 Windows 프로그램에서 이 특이점을 사용하지만 (나는 나 자신을 알지 못합니다)"라고 나와 있습니다.그래서 '스푸핑'하는 것이 가능합니다.GetCommandLineArgs
콘솔 애플리케이션에 대해 이야기하고 있습니다.콘솔 앱은 일반적으로 빠르고 더럽습니다.그래서 이것은 저의 KISS 철학과 일치합니다.
편집 피드백을 보면 유닛 테스트 시스템을 사용할 때 대부분의 다른 솔루션이 작동하지 않는 것 같습니다.실행 가능한 항목이 응용 프로그램이 아니라 테스트 시스템이기 때문에 이러한 종류의 작업이 타당합니다.저는 이것을 확인하지 못했기 때문에 완전히 틀릴 수 있습니다.그렇다면 이 편집 내용을 삭제하겠습니다.
asp.net 웹 앱에 관심이 있는 모든 사람을 위한 것입니다.여기 세 가지 다른 방법의 결과가 있습니다.
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\"에서 물리적으로 실행되고 있습니다."SBS Portal_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;
만약 당신이 a를 찾고 있다면.NET Core 호환 방법, 사용
System.AppContext.BaseDirectory
이 기능은 에서 도입되었습니다.NET Framework 4.6 및 .NET Core 1.0(및 .NET 표준 1.3).AppContext를 참조하십시오.기본 디렉터리 속성입니다.
AppDomain의 기본 대체 버전입니다.현재 도메인.기본 디렉토리입니다.NET 코어
다음과 같은 작업을 수행할 수 있습니다.
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
당신은 이것을 대신 사용할 수 있습니다.
System.Environment.CurrentDirectory
콘솔 응용 프로그램의 경우 다음을 시도할 수 있습니다.
System.IO.Directory.GetCurrentDirectory();
출력(내 로컬 컴퓨터에서):
c:\users\xxxxxxx\documents\visual studio 2012\Projects\ImageHandler\GetDir\bin\디버깅
또는 다음과 같이 시도할 수 있습니다(결국 백슬래시가 추가됨).
AppDomain.CurrentDomain.BaseDirectory
출력:
c:\users\xxxxxxx\documents\visual studio 2012\Projects\ImageHandler\GetDir\bin\Debug\
나는 이 코드를 사용했고 해결책을 얻었습니다.
AppDomain.CurrentDomain.BaseDirectory
다음 행에 응용 프로그램 경로가 표시됩니다.
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
위 솔루션은 다음과 같은 상황에서 올바르게 작동합니다.
- 간단한 앱
- 의회가 있는 다른 도메인에서.GetEntryAssembly()가 null을 반환합니다.
- DLL은 Embedded 리소스에서 바이트 배열로 로드되고 AppDomain에 Assembly로 로드됩니다.로드(바이트 배열OfEmbeddedDll)
- 모와함께와
mkbundle
수 없음)을 사용합니다.
에 간단히 할 수 .System.Windows.Forms
그런 다음 사용합니다.System.Windows.Forms.Application.StartupPath
때처럼
따라서, 더 복잡한 방법이나 반사를 사용할 필요가 없습니다.
사용한 적이 있습니다.
System.AppDomain.CurrentDomain.BaseDirectory
응용 프로그램 폴더와 관련된 경로를 찾고자 할 때이것은 두 ASP 모두에 대해 작동합니다.Net 및 Winform 애플리케이션.또한 시스템에 대한 참조도 필요하지 않습니다.웹 어셈블리.
왜 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());
}
}
}
애플리케이션과 마찬가지로 사용할 수 있습니다.시작 경로:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
에서 제공한 LocalPath를 변환하는 사용자를 보지 못했습니다.코어 반사를 사용 가능한 시스템으로 변환합니다.IO 경로는 다음과 같습니다.
public static string GetApplicationRoot()
{
var exePath = new Uri(System.Reflection.
Assembly.GetExecutingAssembly().CodeBase).LocalPath;
return new FileInfo(exePath).DirectoryName;
}
전체값을반다니합환▁the▁full다가 반환됩니다.C:\\xxx\\xxx
코드가 있는 위치에 대한 형식화된 경로입니다.
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를 두 번 클릭하여 호출해야 하는 경우 사용합니다.
var thisPath = System.IO.Directory.GetCurrentDirectory();
VB.net 에서
My.Application.Info.DirectoryPath
사용할 수 있습니다(응용 프로그램 유형: 클래스 라이브러리).C#에 대해서는 잘 모르겠습니다...파일 이름이 없는 경로를 문자열로 반환합니다.
AppDomain.CurrentDomain.BaseDirectory
타사 참조 파일을 설치 패키지와 함께 참조하는 문제를 해결합니다.
.NET Core 3 이상에서는 .exe 파일이 아닌 .dll을 얻을 수 있습니다.사용할 수 있는 .exe 파일 경로를 가져옵니다.
var appExePath = Process.GetCurrentProcess().MainModule.FileName;
다음과 같은 간단한 코드 행을 사용해 보십시오.
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
.NET 6에는 환경이 있습니다.프로세스 경로.
https://learn.microsoft.com/en-us/dotnet/api/system.environment.processpath?view=net-6.0 을 참조하십시오.
이러한 메소드는 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) + @"\";
}
}
Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName)
내가 시도한 모든 사건에서 나를 위해 일한 유일한 사람입니다.
.NET 6에서, 내 WPF 앱 (<TargetFramework>net6.0-windows</TargetFramework>
) 를 반환합니다..dll
파일 경로:Assembly.GetEntryAssembly()!.Location
대신에.exe
파일. 그들은 다음과 같은 목적으로 도입했습니다.
var path = Environment.ProcessPath; // Note it may be null
현재 실행 프로세스를 시작한 실행 파일의 경로를 반환합니다.돌아온다
null
경로를 사용할 수 없는 경우.
기술과 함정은 계속해서 변화합니다.다음은 를 실행하는 것으로 가정합니다.리눅스의 NET 6 콘솔 앱(윈/맥의 경우 결과가 유사한 패턴을 따를 것입니다. 그냥 교체하십시오./usr/share/
그리고./home/username/
OS의 표준 위치를 사용합니다.).
데모:
Console.WriteLine("Path.GetDirectoryName(Process.GetCurrentProcess()?.MainModule?.FileName) = " + Path.GetDirectoryName(Process.GetCurrentProcess()?.MainModule?.FileName));
Console.WriteLine("Path.GetDirectoryName(Environment.ProcessPath) = " + Path.GetDirectoryName(Environment.ProcessPath));
Console.WriteLine("Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) = " + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
Console.WriteLine("typeof(SomeType).Assembly.Location = " + typeof(SomeType).Assembly.Location);
Console.WriteLine("Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) = " + Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]));
Console.WriteLine("AppDomain.CurrentDomain.BaseDirectory = " + AppDomain.CurrentDomain.BaseDirectory);
Console.WriteLine("System.AppContext.BaseDirectory = " + System.AppContext.BaseDirectory);
결과:
Path.GetDirectoryName(Process.GetCurrentProcess()?.MainModule?.FileName) = /usr/share/dotnet
Path.GetDirectoryName(Environment.ProcessPath) = /usr/share/dotnet
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) = /home/username/myproject/bin/Debug/net6.0
typeof(SomeType).Assembly.Location = /home/username/myproject/bin/Debug/net6.0
Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) = /home/username/myproject/bin/Debug/net6.0
AppDomain.CurrentDomain.BaseDirectory = /home/username/myproject/bin/Debug/net6.0/
System.AppContext.BaseDirectory = /home/username/myproject/bin/Debug/net6.0/
각 접근 방식에는 장단점이 있습니다. 다른 답변을 참조하여 어떤 접근 방식을 사용할 때 사례를 사용하는지 알아보십시오.
제가 운영합니다.NET 6 콘솔 앱과 함께 사용dotnet myapp
그래서 저에게 효과가 있는 것은 다음 중 하나입니다.
typeof(SomeType).Assembly.Location
// or
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
콘솔 + 넷 6에 사용합니다.
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
다음은 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;
}
이제 다음과 같이 사용합니다.
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);
}
언급URL : https://stackoverflow.com/questions/837488/how-can-i-get-the-applications-path-in-a-net-console-application
'programing' 카테고리의 다른 글
NPM: npm을 실행할 때 npm-cli.js를 찾을 수 없습니다. (0) | 2023.05.04 |
---|---|
서로 다른 두 분기의 파일을 비교하는 방법 (0) | 2023.05.04 |
Angular 2 azure 배포 새로 고침 오류: 찾고 있는 리소스가 제거되었거나 이름이 변경되었거나 일시적으로 사용할 수 없습니다. (0) | 2023.05.04 |
ABC를 사용하는 것과 ABC를 사용하는 것 사이에 차이점이 있습니까? (0) | 2023.05.04 |
React Native를 사용할 때 데이터를 저장하기 위한 옵션은 무엇입니까? (iOS 및 Android) (0) | 2023.05.04 |