วิธีที่ดีที่สุดในการรับเส้นทางโฟลเดอร์แอปพลิเคชัน


515

ฉันเห็นว่ามีบางวิธีในการรับเส้นทางโฟลเดอร์แอปพลิเคชัน:

  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory()
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
  7. System.IO.Path.GetDirectory(Application.ExecutablePath)

วิธีที่ดีที่สุดขึ้นอยู่กับสถานการณ์คืออะไร?


9
ทำไมเรามีหลายวิธีในการรับเส้นทางของแอปพลิเคชัน ฉันคิดว่ามีเหตุผลสำหรับแต่ละวิธี
Leo Vo

1
มีข้อผิดพลาดใน # 6: ควรอ่านได้: System.Reflection.Assembly.GetExecutingAssembly (). GetName () .BaseBase), System.IO.Path.GetDirectoryName (Application.ExecutablePath)
BillW

2
ไชโยสำหรับ # 6 ในขณะที่ฉันอยู่ในโครงการเว็บฉันไม่ต้องการตรรกะ Server.MapPath ในห้องสมุดที่โหลด IoC ของฉันซึ่งไม่ใช่เว็บเฉพาะในธรรมชาติ
bkwdesign

ตอนนี้เรามีความน่าเชื่อถือIHostEnvironment.ContentRootPathเข้าถึงได้ผ่านการIHostEnvironmentพึ่งพาการฉีด(ซึ่งมีสิ่งที่มีประโยชน์อื่น ๆ )
Timo

คำตอบ:


519

AppDomain.CurrentDomain.BaseDirectory อาจเป็นประโยชน์มากที่สุดสำหรับการเข้าถึงไฟล์ที่มีตำแหน่งสัมพันธ์กับไดเรกทอรีติดตั้งแอปพลิเคชัน

ในแอปพลิเคชัน ASP.NET สิ่งนี้จะเป็นไดเรกทอรีรูทของแอปพลิเคชันไม่ใช่โฟลเดอร์ย่อยของ Bin ซึ่งอาจเป็นสิ่งที่คุณต้องการ ในแอปพลิเคชันไคลเอนต์มันจะเป็นไดเรกทอรีที่มีไฟล์ปฏิบัติการหลัก

ในแอปพลิเคชัน VSTO 2005 มันจะเป็นไดเรกทอรีที่มีแอสเซมบลีที่ได้รับการจัดการ VSTO สำหรับแอปพลิเคชันของคุณไม่ใช่พูดเส้นทางไปยัง Excel ที่ปฏิบัติการได้

ผู้อื่นอาจส่งคืนไดเรกทอรีต่าง ๆ โดยขึ้นอยู่กับสภาพแวดล้อมของคุณตัวอย่างเช่นดูคำตอบของ @ Vimvq1987

CodeBaseคือสถานที่ที่พบไฟล์และสามารถเป็น URL ที่ขึ้นต้นด้วย http: // ในกรณีLocationนี้อาจจะเป็นแคชดาวน์โหลดแอสเซมบลี CodeBase ไม่รับประกันว่าจะถูกตั้งค่าสำหรับการประกอบในGAC


2
เมื่อทำการทดสอบใน Windows XP 32 บิตจะทำการคืนค่าเริ่มต้นทางลัด
Joshua Son

1
+1 @Joe และสำหรับ VSTO Add-in ระดับเอกสารดูที่นี่

3
โปรดทราบว่าสิ่งนี้จะส่งคืนพา ธ ที่มีแบ็กสแลชในตอนท้าย สิ่งนี้ทำให้ฉันเกิดปัญหาเมื่อทำการจัดรูปแบบสตริงด้วยผลลัพธ์ที่จะผ่านเป็นอาร์กิวเมนต์ของกระบวนการ
avenmore

19
@avenmore - หากคุณกำลังจัดรูปแบบสตริงเพื่อสร้างเส้นทางให้พิจารณาใช้Path.Combineแทน สิ่งนี้จะดูแลแบ็กสแลชต่อท้ายสำหรับคุณ
โจ

1
นี่เป็นการส่งคืนโฟลเดอร์ bin / debug สำหรับฉันใน VS 2017 ไม่ใช่ไดเรกทอรีราก
SmoveBB

86
  1. Application.StartupPathและ 7 System.IO.Path.GetDirectoryName(Application.ExecutablePath)- ใช้ได้สำหรับแอปพลิเคชัน Windows Forms เท่านั้น

  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)

    กำลังจะให้สิ่งที่คุณต้องการ: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101"ซึ่งเป็นหน้าที่คุณกำลังเรียกใช้อยู่

  3. AppDomain.CurrentDomain.BaseDirectoryสำหรับเว็บแอปพลิเคชั่นอาจมีประโยชน์และจะส่งคืนบางอย่างเช่น"C:\\hg\\Services\\Services\\Services.Website\\"ซึ่งเป็นไดเรกทอรีฐานและค่อนข้างมีประโยชน์

  4. System.IO.Directory.GetCurrentDirectory() และ 5 Environment.CurrentDirectory

จะทำให้คุณทราบตำแหน่งที่กระบวนการถูกไล่ออกจาก - ดังนั้นสำหรับแอปพลิเคชันเว็บที่ทำงานในโหมดแก้ไขข้อบกพร่องจาก Visual Studio "C:\\Program Files (x86)\\IIS Express"

  1. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

จะทำให้คุณทราบตำแหน่งที่.dllใช้งานโค้ดสำหรับแอปพลิเคชันเว็บที่เป็นไปได้"file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

ตอนนี้ในกรณีของตัวอย่างเช่นแอปคอนโซลคะแนน 2-6 จะเป็นไดเรกทอรีที่.exe ไฟล์อยู่

หวังว่านี่จะช่วยคุณประหยัดเวลา


2
ค่อนข้างแน่ใจว่าต้องการ "โฟลเดอร์ปัจจุบัน" มีความเกี่ยวข้องเฉพาะกับแอปที่ไม่ใช่เว็บอยู่แล้ว ...
Nyerguds

2
นี่คือคำตอบ
P.Brian.Mackey

59

โปรดทราบว่าวิธีการเหล่านี้ไม่ทั้งหมดจะคืนค่าเดียวกัน ในบางกรณีพวกเขาสามารถส่งคืนค่าเดียวกัน แต่ระวังวัตถุประสงค์ของพวกเขาจะแตกต่างกัน:

Application.StartupPath

ส่งคืนStartupPathพารามิเตอร์ (สามารถตั้งค่าเมื่อเรียกใช้แอปพลิเคชัน)

System.IO.Directory.GetCurrentDirectory()

ส่งคืนไดเรกทอรีปัจจุบันซึ่งอาจจะใช่หรือไม่ใช่โฟลเดอร์ที่เป็นที่ตั้งของแอปพลิเคชัน Environment.CurrentDirectoryเดียวกันจะไปสำหรับ ในกรณีที่คุณใช้สิ่งนี้ในไฟล์ DLL มันจะคืนค่าพา ธ ที่กระบวนการทำงานอยู่ (โดยเฉพาะใน ASP.NET)


7
ได้โปรดได้โปรดได้โปรดอย่าใช้GetCurrentDirectory()สำหรับความรักในการทำสิ่งต่าง ๆ จากเส้นทางที่แตกต่างกัน! :(
kayleeFrye_onDeck

@kayleeFrye_onDeck คุณไม่ได้ให้เหตุผลกับคำถามก่อนหน้านี้
nless

10

สำหรับเว็บแอปพลิเคชันในการรับไดเรกทอรีรูทเว็บแอปพลิเคชันปัจจุบันโดยทั่วไปจะเรียกผ่านหน้าเว็บสำหรับคำขอขาเข้าปัจจุบัน

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

คำอธิบายรหัสข้างต้น


6

ฉันเริ่มต้นกระบวนการจากบริการ Windows ผ่าน Win32 API ในเซสชันจากผู้ใช้ที่เข้าสู่ระบบจริง (ในเซสชันตัวจัดการงาน 1 ไม่ใช่ 0) ในเรื่องนี้เราสามารถทำความรู้จักกับตัวแปรที่ดีที่สุด

สำหรับทั้ง 7 กรณีจากคำถามข้างต้นผลลัพธ์ต่อไปนี้คือ:

Path1: C:\Program Files (x86)\MyProgram
Path2: C:\Program Files (x86)\MyProgram
Path3: C:\Program Files (x86)\MyProgram\
Path4: C:\Windows\system32
Path5: C:\Windows\system32
Path6: file:\C:\Program Files (x86)\MyProgram
Path7: C:\Program Files (x86)\MyProgram

อาจเป็นประโยชน์สำหรับคุณบางคนทำสิ่งเดียวกันเมื่อคุณค้นหาตัวแปรที่ดีที่สุดสำหรับกรณีของคุณ


4
คำตอบที่เกี่ยวข้องมาก คนจำนวนมากลืมว่า "ไดเรกทอรีทำงาน"! = "ไดเรกทอรีโปรแกรม"
Nyerguds

3

จากประสบการณ์ของฉันวิธีที่ดีที่สุดคือการรวมกันของสิ่งเหล่านี้

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase จะให้โฟลเดอร์ bin แก่คุณ
  2. Directory.GetCurrentDirectory() ทำงานได้ดีบน. Net Core แต่ไม่ใช่. Net และจะให้ไดเรกทอรีรูทของโครงการแก่คุณ
  3. System.AppContext.BaseDirectoryและAppDomain.CurrentDomain.BaseDirectory ทำงานได้ดีใน. Net แต่ไม่ใช่. core สุทธิและจะให้ไดเรกทอรีรูทของโครงการแก่คุณ

ในไลบรารีคลาสที่ควรจะเป็น target.Net และ. Net core ฉันตรวจสอบเฟรมเวิร์กที่โฮสต์ไลบรารีและเลือกอย่างใดอย่างหนึ่ง


2

ฉันใช้มันสำเร็จแล้ว

System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

มันทำงานได้แม้ในlinqpad


1
สิ่งนี้ขาดวงเล็บเหลี่ยมเปิดของ GetCurrentProcess btw ทำการประเมินเป็น C: \ Program Files \ dotnet ในโครงการ. net หลักของฉันในขณะที่ทำการดีบักใน visual studio เพราะนั่นคือจุดที่ dotnet.exe ตั้งอยู่
t0b4cc0

1

ไดเรกทอรีราก:

DriveInfo cDrive = new DriveInfo(System.Environment.CurrentDirectory);
var driverPath = cDrive.RootDirectory;

1
สิ่งนี้ดูเหมือนว่าจะได้รับไดเรกทอรีการทำงานปัจจุบันในขณะที่อาจมีประโยชน์บางครั้งก็ไม่รับประกันว่าจะเป็นเส้นทาง EXE
krowe2


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.