コンソールアプリケーションでアプリケーションのパスを確認する方法
にWindowsフォーム、 私は使えますApplication.StartupPath
現在のパスを見つけるためですが、これはコンソールアプリケーションでは利用できないようです。
System.Reflection.Assembly.GetExecutingAssembly()
。Location
1
と組み合わせるSystem.IO.Path.GetDirectoryName
必要なのはディレクトリだけです。
1Mr.Mindorのコメントによると:
System.Reflection.Assembly.GetExecutingAssembly().Location
実行中のアセンブリが現在配置されている場所を返します。実行中でない場合は、アセンブリが配置されている場所である場合とそうでない場合があります。シャドウコピーアセンブリの場合は、一時ディレクトリにパスを取得します。System.Reflection.Assembly.GetExecutingAssembly().CodeBase
アセンブリの「恒久的な」パスを返します。
GetExecutingAssembly
そのアセンブリを返します現在実行中のコードが含まれています。これは必ずしもコンソールではないかもしれません。EXEアセンブリ。まったく別の場所からロードされたアセンブリかもしれません。あなたが使用する必要がありますGetEntryAssembly
!また注意してくださいCodeBase
アセンブリがGAC内にあるときは設定されない可能性があります。より良い代替手段はAppDomain.CurrentDomain.BaseDirectory
。 - bitbonk
現在のアプリケーションディレクトリを取得するには、次のコードを使用できます。
AppDomain.CurrentDomain.BaseDirectory
BaseDirectory
実行時に設定できますか?ゲッターしかありません。 - bitbonk
アプリケーションのディレクトリを見つけるには、目的に応じて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);
var localDirectory = new Uri(directory).LocalPath;
- Okuma.Scott
おそらく少し遅いですが、これは言及する価値があります。
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"から実行されているため、最初の解決策は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パスを許可しないという例外が発生します。 - vapcguy#
キャラクター)。識別子とそれに続くすべてのものは、結果のパスから切り捨てられます。 - Marknew Uri
そしてSystem.IO.Path.GetDirectoryName
?それはあなたの代わりに通常のパス文字列を与えるUri
。 - Timo
あなたはこれをすることを探しているかもしれません:
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の推奨置換です。
exeファイルがそれをダブルクリックして呼び出されることになっている場合、私はこれを使用します
var thisPath = System.IO.Directory.GetCurrentDirectory();
利用した
System.AppDomain.CurrentDomain.BaseDirectory
アプリケーションフォルダへの相対パスを見つけたいとき。これは、ASP.Netとwinformの両方のアプリケーションで機能します。 System.Webアセンブリへの参照も必要ありません。
あなたは単にあなたのプロジェクト参照に追加することができますSystem.Windows.Forms
それからSystem.Windows.Forms.Application.StartupPath
いつものように 。
そのため、より複雑な方法やリフレクションを使用する必要はありません。
つまり、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");
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);
AppDomain.CurrentDomain.BaseDirectory
サードパーティの参照ファイルをインストールパッケージで参照することで問題を解決します。
VB.netで
My.Application.Info.DirectoryPath
私のために動作します(アプリケーションタイプ:クラスライブラリ)。 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);
次の行はあなたにアプリケーションパスを与えるでしょう:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
上記の解決策は、以下の状況で適切に機能しています。
.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"形式のパスが返されます。
次のコードを使用すると、アプリケーションのフルパスを取得できます。
class Program
{
static void Main(string[] args)
{
string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
WriteLine($"ApplicationPath ---{AppPath}");
//OutPut// //ApplicationPath---C:\Users\TestUser\source\repos\ThreadStack\ThreadStack\bin\Debug\ThreadStack.exe
ReadLine();
}
}
これが信頼できる解決策です。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);
}