Konsol uygulamasında uygulamanın yolunu nasıl bulurum?
In Windows Forms , ben kullanabilirsiniz Application.StartupPath
geçerli yolu bulmak için, ama bu bir konsol uygulamasında kullanılabilir olmasını görünmüyor.
Konsol uygulamasında uygulamanın yolunu nasıl bulurum?
In Windows Forms , ben kullanabilirsiniz Application.StartupPath
geçerli yolu bulmak için, ama bu bir konsol uygulamasında kullanılabilir olmasını görünmüyor.
Yanıtlar:
System.Reflection.Assembly.GetExecutingAssembly()
.Location
1
System.IO.Path.GetDirectoryName
İstediğiniz tek şey dizinse ile birleştirin .
1 Mr.Mindor'un yorumuna göre: Yürütme
System.Reflection.Assembly.GetExecutingAssembly().Location
derlemesinin şu anda bulunduğu yeri döndürür; yürütme sırasında derlemenin bulunduğu yer olabilir veya olmayabilir. Gölge kopyalama derlemeleri durumunda, geçici bir dizinde bir yol alırsınız.System.Reflection.Assembly.GetExecutingAssembly().CodeBase
montajın 'kalıcı' yolunu döndürür.
GetExecutingAssembly
yürütülmekte olan kodu içeren derleme döndürür . Bu mutlaka konsol .exe derlemesi olmayabilir . Tamamen farklı bir yerden yüklenmiş bir montaj olabilir. Kullanmanız gerekecek GetEntryAssembly
! Ayrıca CodeBase
montaj GAC'deyken ayarlanamayabileceğini unutmayın . Daha iyi bir alternatif AppDomain.CurrentDomain.BaseDirectory
.
Geçerli uygulama dizinini almak için aşağıdaki kodu kullanabilirsiniz.
AppDomain.CurrentDomain.BaseDirectory
BaseDirectory
çalışma zamanında ayarlanabileceğini düşündüren nedir ? Sadece bir alıcı var.
Uygulamanın dizinini bulmak için iki seçeneğiniz vardır; seçtiğiniz dizin amacınıza bağlıdır.
// 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;
Muhtemelen biraz geç ama bu bir kayda değer:
Environment.GetCommandLineArgs()[0];
Veya sadece dizin yolunu almak için daha doğru:
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
Düzenle:
Oldukça az sayıda kişi GetCommandLineArgs
, program adını döndürmenin garanti edilmediğine dikkat çekti . Bkz komut satırında ilk kelimeyi sadece Kongre tarafından programın adıdır . Makale, "Çok az sayıda Windows programı bu tuhaflığı kullanmasına rağmen (kendimin farkında değilim)" yazıyor. Bu yüzden 'parodi' yapmak mümkündür GetCommandLineArgs
, ancak bir konsol uygulamasından bahsediyoruz. Konsol uygulamaları genellikle hızlı ve kirlidir. Bu benim KISS felsefeme uyuyor.
Asp.net web uygulamaları ile ilgilenen herkes için. İşte 3 farklı yöntemin sonuçları
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);
}
sonuç
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
uygulama fiziksel olarak "C: \ inetpub \ SBSPortal_staging" ile çalışıyor, bu nedenle ilk çözüm kesinlikle web uygulamaları için uygun değil.
Yukarıdaki cevap ihtiyacım olanın% 90'ıydı, ama benim için düzenli bir yol yerine bir Uri döndürdü.
MSDN forumları postasında açıklandığı gibi, URI yolu normal dosyayoluna nasıl dönüştürülür? , Aşağıdakileri kullandım:
// 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)
, bu size URI yollarına izin vermediği istisnasını verecektir ...
#
karakter) içeren yollar için geçerli değildir . Tanımlayıcı ve onu izleyen her şey elde edilen yoldan kesilir.
new Uri
ve System.IO.Path.GetDirectoryName
? Bu size a yerine normal bir yol dizesi verir Uri
.
bunun yerine bunu kullanabilirsiniz.
System.Environment.CurrentDirectory
.NET Core uyumlu bir yol arıyorsanız,
System.AppContext.BaseDirectory
Bu, .NET Framework 4.6 ve .NET Core 1.0'da (ve .NET Standard 1.3'te) tanıtıldı. Bkz . AppContext.BaseDirectory Özelliği .
Bu sayfaya göre ,
Bu, .NET Core'da AppDomain.CurrentDomain.BaseDirectory için tercih edilen yedek
Process.GetCurrentProcess().MainModule.FileName
Konsol Uygulamaları için şunu deneyebilirsiniz:
System.IO.Directory.GetCurrentDirectory();
Çıktı (yerel makinemde):
c: \ users \ xxxxxxx \ belgeler \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug
Ya da deneyebilirsiniz (sonunda ek bir ters eğik çizgi var):
AppDomain.CurrentDomain.BaseDirectory
Çıktı:
c: \ users \ xxxxxxx \ belgeler \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug \
BaseDirectory
zamanında ayarlanabilir. Doğru olması garanti EDİLMEZ"
Bu kodu kullandım ve çözüm olsun.
AppDomain.CurrentDomain.BaseDirectory
Proje referanslarınıza ekleyebilir System.Windows.Forms
ve ardındanSystem.Windows.Forms.Application.StartupPath
her zamanki gibi .
Bu nedenle, daha karmaşık yöntemlere veya yansımayı kullanmaya gerek yoktur.
Aşağıdaki satır size bir uygulama yolu verecektir:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
Yukarıdaki çözüm aşağıdaki durumlarda düzgün çalışıyor:
mkbundle
demetleri ile (başka yöntem işe yaramıyor)Eğer exe çift tıklayarak çağrılması gerekiyorsa bunu kullanıyorum
var thisPath = System.IO.Directory.GetCurrentDirectory();
Kullandım
System.AppDomain.CurrentDomain.BaseDirectory
uygulamalar klasörüne göre bir yol bulmak istediğimde. Bu hem ASP.Net hem de winform uygulamaları için geçerlidir. Ayrıca System.Web derlemelerine başvuru gerektirmez.
Yani, ap / invoke yöntemi neden olmasın?
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());
}
}
}
Tıpkı Application.tartupPath gibi kullanırsınız:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
Assembly.GetEntryAssembly().Location
veya Assembly.GetExecutingAssembly().Location
System.IO.Path.GetDirectoryName()
Yalnızca dizini almak için ile birlikte kullanın .
Çoğu durumda dizin aynı olsa da, yollar GetEntryAssembly()
ve GetExecutingAssembly()
farklı olabilir.
Bununla birlikte , giriş modülü yönetilmezse (örn. C ++ veya VB6 yürütülebilir) GetEntryAssembly()
bunun geri dönebileceğini bilmelisiniz null
. Bu gibi durumlarda GetModuleFileName
Win32 API'den kullanmak mümkündür :
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
AppDomain.CurrentDomain.BaseDirectory
Yükleme paketleriyle birlikte 3. taraf referans dosyalarına başvurma sorununu çözecektir.
Bu yöntemlerin hiçbiri exe'ye sembolik bir bağlantı kullanmak gibi özel durumlarda işe yaramaz, gerçek exe'ye değil bağlantının konumunu döndürürler.
Bunu yapmak için QueryFullProcessImageName kullanabilirsiniz :
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) + @"\";
}
}
Bu basit kod satırını deneyin:
string exePath = Path.GetDirectoryName( Application.ExecutablePath);
Başka bir çözüm, geçerli yolu gösteren göreli yollar kullanmaktır:
Path.GetFullPath(".")
.Net Core yansıması tarafından sağlanan LocalPath'i kullanılabilir bir System.IO yoluna dönüştüren kimseyi görmedim, işte sürümüm.
public static string GetApplicationRoot()
{
var exePath = new Uri(System.Reflection.
Assembly.GetExecutingAssembly().CodeBase).LocalPath;
return new FileInfo(exePath).DirectoryName;
}
Bu, kodunuzun bulunduğu yere "C: \ xxx \ xxx" biçimli yolun tamamını döndürür.
Yürütülebilir yolu elde etmenin birçok yolu vardır, hangisini kullanmalıyız, burada ihtiyaçlarımıza bağlıdır, farklı yöntemleri tartışan bir bağlantıdır.
İşte 32bit ve 64bit uygulamalarla çalışan güvenilir bir çözüm .
Bu referansları ekleyin:
System.Diagnostics kullanarak;
System.Management kullanarak;
Bu yöntemi projenize ekleyin:
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;
}
Şimdi şöyle kullanın:
int RootProcessId = Process.GetCurrentProcess().Id;
GetProcessPath(RootProcessId);
İşlemin kimliğini biliyorsanız, bu yöntemin karşılık gelen ExecutePath değerini döndüreceğini unutmayın.
Ekstra, ilgilenenler için:
Process.GetProcesses()
... şu anda çalışan tüm işlemlerin bir dizisini verecek ve ...
Process.GetCurrentProcess()
... mevcut süreçle birlikte bilgileri, örneğin Kimlik, vb. ve ayrıca sınırlı kontrol, örneğin Öldür, vb.
Solution Explorer'ı kullanarak proje içinde Kaynaklar olarak bir klasör adı oluşturabilir, ardından Kaynaklar'ın içine bir dosya yapıştırabilirsiniz.
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);
}