してほしいのですが、アプリケーションのパス。純コンソール-アプリケーション?
-
10-07-2019 - |
質問
か、アプリケーションのパスコンソール-アプリケーション?
に Windows Forms, ご利用できます Application.StartupPath
の電流経路が、このように見えません利用可能なコンソール-アプリケーション.
解決
System.Reflection.Assembly.GetExecutingAssembly ()
。 場所
1
System.IOと組み合わせます。 Path.GetDirectoryName
必要なのがディレクトリのみの場合。
1 Mindor氏のコメント:
System.Reflection.Assembly.GetExecutingAssembly()。Location
は、実行中のアセンブリが現在配置されている場所を返します。アセンブリをシャドウコピーする場合、一時ディレクトリにパスを取得します。System.Reflection.Assembly.GetExecutingAssembly()。 CodeBase
は、アセンブリの「永続的な」パスを返します。
他のヒント
次のコードを使用して、現在のアプリケーションディレクトリを取得できます。
AppDomain.CurrentDomain.BaseDirectory
アプリケーションのディレクトリを見つけるための2つのオプションがありますが、選択する目的は目的によって異なります。
// 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 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アプリには適していません。
上記の答えは必要なものの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;
これを行うことを検討している可能性があります:
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 \ Debug
または試すことができます(最後に追加のバックスラッシュがあります):
AppDomain.CurrentDomain.BaseDirectory
出力:
c:\ users \ xxxxxxx \ documents \ visual studio 2012 \ Projects \ ImageHandler \ GetDir \ bin \ Debug \
このコードを使用して解決策を取得しました。
AppDomain.CurrentDomain.BaseDirectory
.NET Coreと互換性のある方法を探している場合は、
System.AppContext.BaseDirectory
これは、.NET Framework 4.6および.NET Core 1.0(および.NET Standard 1.3)で導入されました。参照: AppContext.BaseDirectoryプロパティ。
これは、.NET CoreのAppDomain.CurrentDomain.BaseDirectoryの代わりに推奨されるものです
使用しました
System.AppDomain.CurrentDomain.BaseDirectory
アプリケーションフォルダーへの相対パスを検索する場合。これは、ASP.Netアプリケーションとwinformアプリケーションの両方で機能します。 System.Webアセンブリへの参照も必要ありません。
単にプロジェクト参照 System.Windows.Forms
に追加してから、通常どおり System.Windows.Forms.Application.StartupPath
を使用できます。
したがって、より複雑なメソッドやリフレクションを使用する必要はありません。
exeをダブルクリックして呼び出されることになっている場合、これを使用します
var thisPath = System.IO.Directory.GetCurrentDirectory();
つまり、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());
}
}
}
Application.StartupPathのように使用します:
Console.WriteLine("The path to this executable is: " + AppInfo.StartupPath + "\\" + System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
次の行は、アプリケーションパスを示します。
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
上記のソリューションは、次の状況で適切に機能しています。
- シンプルなアプリ
- Assembly.GetEntryAssembly()がnullを返す別のドメイン
- DLLは、組み込みリソースからバイト配列としてロードされ、Assembly.Load(byteArrayOfEmbeddedDll)としてAppDomainにロードされます
Assembly.GetEntryAssembly().Location
または Assembly.GetExecutingAssembly().Location
組み合わせ使用 System.IO.Path.GetDirectoryName()
の取得のみをクリックします。
の経路から GetEntryAssembly()
や GetExecutingAssembly()
きく異なるものの、ほとんどの場合、ディレクトリが同じでなければならない。
と GetEntryAssembly()
いである"ことを認識しこの復帰できる null
応募する場合はモジュールはポリシー(ie C++またはVB6実行可能).その場合の使用が可能で GetModuleFileName
からのWin32API:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
AppDomain.CurrentDomain.BaseDirectory
インストールパッケージでサードパーティの参照ファイルを参照するように問題を解決します。
VB.netで
My.Application.Info.DirectoryPath
works for me(アプリケーションの種類:クラスライブラリ)。 C#についてわからない... ファイル名なしのパスを文字列として返します
これらのメソッドはいずれも、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);
別の解決策は、現在のパスを指す相対パスを使用することです:
Path.GetFullPath(".")
.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"を返します。コードがある場所へのフォーマットされたパス。
実行可能パスを取得するには多くの方法がありますが、使用する方法はニーズに応じて異なります。ここでは、さまざまな方法を説明するリンクがあります。
32bit および 64bit アプリケーションで動作する信頼できるソリューションです。
これらの参照を追加します:
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);
}