කොන්සෝල යෙදුමක යෙදුමේ මාර්ගය සොයා ගන්නේ කෙසේද?
දී වින්ඩෝස් ආකෘති පත්ර , මම භාවිතා කළ හැකි Application.StartupPath
වත්මන් මාර්ගය සොයා ගැනීමට, නමුත් මේ කරන කොන්සෝල අයදුම් ලබා ගත යුතු බවක් පෙනෙන්නට නැත.
කොන්සෝල යෙදුමක යෙදුමේ මාර්ගය සොයා ගන්නේ කෙසේද?
දී වින්ඩෝස් ආකෘති පත්ර , මම භාවිතා කළ හැකි Application.StartupPath
වත්මන් මාර්ගය සොයා ගැනීමට, නමුත් මේ කරන කොන්සෝල අයදුම් ලබා ගත යුතු බවක් පෙනෙන්නට නැත.
Answers:
System.Reflection.Assembly.GetExecutingAssembly()
. 1Location
System.IO.Path.GetDirectoryName
ඔබට අවශ්ය වන්නේ නාමාවලිය නම් එය ඒකාබද්ධ කරන්න.
1 මින්ඩෝර් මහතාගේ ප්රකාශයට අනුව:
System.Reflection.Assembly.GetExecutingAssembly().Location
ක්රියාත්මක වන එකලස් කිරීම දැනට පවතින ස්ථානයට නැවත පැමිණේ. සෙවනැලි පිටපත් කිරීමේ එකලස් කිරීමේදී, ඔබට තාවකාලික නාමාවලියක මාර්ගයක් ලැබෙනු ඇත.System.Reflection.Assembly.GetExecutingAssembly().CodeBase
එකලස් කිරීමේ 'ස්ථිර' මාර්ගය නැවත ලබා දෙනු ඇත.
GetExecutingAssembly
දැනට ක්රියාත්මක වන කේතය අඩංගු එකලස් කිරීම . මෙය අනිවාර්යයෙන්ම කොන්සෝලය නොවිය හැකිය .exe එකලස් කිරීම. එය සම්පූර්ණයෙන්ම වෙනස් ස්ථානයකින් පටවා ඇති එකලස් කිරීමක් විය හැකිය. ඔබට භාවිතා කිරීමට සිදුවනු ඇත GetEntryAssembly
! CodeBase
එකලස් කිරීම GAC හි ඇති විට සැකසිය නොහැකි බව සලකන්න . වඩා හොඳ විකල්පය නම් AppDomain.CurrentDomain.BaseDirectory
.
Application
කොන්සෝල යෙදුම් සඳහා නොපවතී.
වත්මන් යෙදුම් නාමාවලිය ලබා ගැනීමට ඔබට පහත කේතය භාවිතා කළ හැකිය.
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
වැඩසටහනේ නම නැවත ලබා දීම සහතික නොවන බව බොහෝ දෙනෙක් පෙන්වා දී ඇත . විධාන රේඛාවේ පළමු වචනය බලන්න වැඩසටහනේ නම සම්මුතියෙන් පමණි . ලිපියේ සඳහන් වන්නේ “වින්ඩෝස් වැඩසටහන් ඉතා ස්වල්පයක් මෙම විකාරය භාවිතා කළත් (මම මා ගැන කිසිවක් නොදනිමි)”. එබැවින් 'කොල්ලකෑම' කළ හැකි GetCommandLineArgs
නමුත් අපි කතා කරන්නේ කොන්සෝල යෙදුමක් ගැන ය. කොන්සෝල යෙදුම් සාමාන්යයෙන් ඉක්මන් හා අපිරිසිදු ය. එබැවින් මෙය මගේ KISS දර්ශනයට ගැලපේ.
Asp.net වෙබ් යෙදුම් ගැන උනන්දුවක් දක්වන ඕනෑම කෙනෙකුට. මෙන්න මගේ ක්රම 3 ක ප්රති results ල
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% ක් වූ නමුත් මට සාමාන්ය මාර්ගයක් වෙනුවට යූරි එකක් ආපසු ලබා දුන්නේය.
එම්එස්ඩීඑන් සංසද පෝස්ට් එකේ විස්තර කර ඇති පරිදි, යූආර්අයි මාර්ගය සාමාන්ය ගොනු මාර්ගයක් බවට පරිවර්තනය කරන්නේ කෙසේද? , මම පහත සඳහන් දෑ භාවිතා කළෙමි:
// 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)
, එය ඔබට
#
චරිතය) අඩංගු මාර්ග සඳහා ක්රියා නොකරයි . හඳුනාගැනීමේ යන්ත්රය සහ එය අනුගමනය කරන සෑම දෙයක්ම ප්රති ing ල මාර්ගයෙන් කපා දමනු ලැබේ.
new Uri
හා System.IO.Path.GetDirectoryName
? එය ඔබට a වෙනුවට සාමාන්ය මාර්ග නූලක් ලබා දෙයි Uri
.
ඔබ .NET Core අනුකූල ක්රමයක් සොයන්නේ නම්, භාවිතා කරන්න
System.AppContext.BaseDirectory
මෙය .NET Framework 4.6 සහ .NET Core 1.0 (සහ .NET Standard 1.3) වලින් හඳුන්වා දෙන ලදී. බලන්න: AppContext.BaseDirectory Property .
මෙම පිටුවට අනුව ,
.NET Core හි AppDomain.CurrentDomain.BaseDirectory සඳහා වඩාත් සුදුසු ආදේශනය මෙයයි
Process.GetCurrentProcess().MainModule.FileName
ඔබට ඒ වෙනුවට මෙය භාවිතා කළ හැකිය.
System.Environment.CurrentDirectory
කොන්සෝල යෙදුම් සඳහා, ඔබට මෙය උත්සාහ කළ හැකිය:
System.IO.Directory.GetCurrentDirectory();
ප්රතිදානය (මගේ දේශීය යන්ත්රයේ):
c: \ පරිශීලකයින් \ xxxxxxx \ ලේඛන \ දෘශ්ය චිත්රාගාරය 2012 \ ව්යාපෘති \ ImageHandler \ GetDir \ bin \ නිදොස්කරණය
නැතහොත් ඔබට උත්සාහ කළ හැකිය (අවසානයේ අමතර බැක්ස්ලෑෂ් එකක් ඇත):
AppDomain.CurrentDomain.BaseDirectory
ප්රතිදානය:
c: \ පරිශීලකයින් \ xxxxxxx \ ලේඛන \ දෘශ්ය චිත්රාගාරය 2012 \ ව්යාපෘති \ ImageHandler \ GetDir \ bin \ Debug \
BaseDirectory
ක්රියාත්මක වන වේලාවේදී එය සැකසිය හැකිය. එය නිවැරදි බවට සහතික නොවේ"
මම මෙම කේතය භාවිතා කර විසඳුම ලබා ගත්තා.
AppDomain.CurrentDomain.BaseDirectory
ඔබට ඔබේ ව්යාපෘති යොමු කිරීම් වලට එකතු කර සුපුරුදු පරිදි System.Windows.Forms
භාවිතා කළ System.Windows.Forms.Application.StartupPath
හැකිය.
එබැවින්, වඩාත් සංකීර්ණ ක්රම හෝ පරාවර්තනය භාවිතා කිරීම අවශ්ය නොවේ.
පහත දැක්වෙන පේළිය මඟින් ඔබට යෙදුම් මාර්ගයක් ලබා දෙනු ඇත:
var applicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)
ඉහත විසඳුම පහත සඳහන් අවස්ථාවන්හිදී නිසි ලෙස ක්රියාත්මක වේ:
mkbundle
මිටි සමඟ (වෙනත් ක්රම ක්රියාත්මක නොවේ)මම මෙය භාවිතා කරන්නේ exe දෙවරක් ක්ලික් කිරීමෙන් කැඳවිය යුතු නම්
var thisPath = System.IO.Directory.GetCurrentDirectory();
මම භාවිතා කර ඇත
System.AppDomain.CurrentDomain.BaseDirectory
යෙදුම් ෆෝල්ඩරයකට සාපේක්ෂව මාර්ගයක් සොයා ගැනීමට මට අවශ්ය වූ විට. මෙය ASP.Net සහ winform යෙදුම් සඳහා ක්රියා කරයි. එයට System.Web එකලස් කිරීම් පිළිබඳ කිසිදු සඳහනක් අවශ්ය නොවේ.
මම කිව්වේ, ඇයි ap / invoke method?
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
ස්ථාපන පැකේජ සමඟ තෙවන පාර්ශවීය යොමු ලිපිගොනු යොමු කිරීම සඳහා ගැටළුව විසඳනු ඇත.
මෙම ක්රම කිසිවක් විශේෂ අවස්ථා වලදී 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);
.නෙට් කෝර් පරාවර්තනය භාවිතා කළ හැකි පද්ධතියක් බවට කිසිවෙකු පරිවර්තනය කරන බවක් මා දුටුවේ නැත. අයිඕ මාවත මෙන්න මගේ අනුවාදය.
public static string GetApplicationRoot()
{
var exePath = new Uri(System.Reflection.
Assembly.GetExecutingAssembly().CodeBase).LocalPath;
return new FileInfo(exePath).DirectoryName;
}
මෙය ඔබගේ කේතය ඇති තැනට සම්පූර්ණ "C: \ xxx \ xxx" ආකෘතිගත මාර්ගය ලබා දෙනු ඇත.
තවත් විසඳුමක් වන්නේ වත්මන් මාර්ගයට යොමු වන සාපේක්ෂ මාර්ග භාවිතා කිරීමයි:
Path.GetFullPath(".")
Path.GetDirectoryName (System.Diagnostics.Process.GetCurrentProcess (). MainModule.FileName) මා උත්සාහ කළ සෑම අවස්ථාවකම මා වෙනුවෙන් වැඩ කළ එකම එක එයයි.
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);
ක්රියාවලියේ හැඳුනුම්පත ඔබ දන්නේ නම්, මෙම ක්රමය මඟින් අනුරූපී ක්රියාත්මක කිරීමේ මාර්ගය නැවත ලබා දෙන බව සලකන්න.
අමතර, උනන්දුවක් දක්වන අය සඳහා:
Process.GetProcesses()
... දැනට ක්රියාත්මක වන සියලුම ක්රියාවලීන් සමූහයක් ඔබට ලබා දෙනු ඇත, සහ ...
Process.GetCurrentProcess()
... ඔවුන්ගේ තොරතුරු සමඟ වර්තමාන ක්රියාවලිය ඔබට ලබා දෙනු ඇත. උදා: හැඳුනුම්පත් යනාදිය සහ සීමිත පාලනයක් උදා.
ක්රියාත්මක කළ හැකි මාර්ගයක් ලබා ගැනීමට බොහෝ ක්රම තිබේ, අප එය භාවිතා කළ යුත්තේ අපගේ අවශ්යතා මත ය. මෙහි විවිධ ක්රම සාකච්ඡා කරන සබැඳියකි.
සොලියුෂන් එක්ස්ප්ලෝරර් භාවිතයෙන් ඔබට ව්යාපෘතිය තුළ සම්පත් ලෙස ෆෝල්ඩර නාමයක් සෑදිය හැකිය, එවිට ඔබට සම්පත් තුළ ගොනුවක් ඇලවිය හැකිය.
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);
}