2009-06-11 35 views

Trả lời

112
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName 
+7

Điều này có xu hướng thêm ".vhost". trong tên tệp, một vấn đề không xuất hiện nếu sử dụng System.Reflection.Assembly.GetEntryAssembly() .Địa điểm (xem câu trả lời thay thế). – Contango

+4

@Contango, đó là do sử dụng "Visual Studio Hosting Process" trong VS. – LuddyPants

+0

Để thử nghiệm đơn vị trong VS 2012. ProcessName: vstest.executionengine.x86 ConfigurationFile: C: \ TFS \ Tests \ MyData.Tests.v4.0 \ bin \ Debug \ MyData.Tests.v4.0.dll.config MainModule.FileName: C: \ FILOGRAM (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionengine.x86.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName : UnitTestAdapter: Chạy thử nghiệm – Kiquenet

7

Tôi nghĩ rằng điều này sẽ là những gì bạn muốn:

System.Reflection.Assembly.GetEntryAssembly().Location 

lợi nhuận này lắp ráp lần đầu tiên được nạp khi quá trình khởi động, mà dường như là những gì bạn muốn.

GetCallingAssembly không nhất thiết phải trả lại assembly bạn muốn trong trường hợp chung, vì nó trả về assembly có chứa phương thức ngay lập tức cao hơn trong ngăn gọi (tức là nó có thể nằm trong cùng một DLL).

+0

Tôi không chắc chắn về GetCallingAssembly() - không phải là sự trở lại lắp ráp có chứa các phương pháp gọi điện thoại (một lên trên ngăn xếp cuộc gọi)? Đây chỉ là khả năng là thư viện hơn là thực thi. –

+0

@Martin: Vâng, bạn nói đúng. GetCallingAssembly có thể làm việc/được appropiate trong một số trường hợp, nhưng có vẻ như anh ta muốn GetEntryAssembly ở đây. – Noldorin

3

Assembly.GetEntryAssembly()

70

Nếu bạn muốn thực thi:

System.Reflection.Assembly.GetEntryAssembly().Location 

Nếu bạn muốn lắp ráp đó là tốn nhiều thư viện của bạn (mà có thể là lắp ráp tương tự như trên, nếu mã của bạn được gọi là trực tiếp từ một lớp trong tệp thi hành của bạn):

System.Reflection.Assembly.GetCallingAssembly().Location 

Nếu bạn muốn e chỉ là tập tin tên và không phải là con đường, sử dụng:

Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location) 
+6

GetEntryAssembly có thể trả về null nếu được gọi từ mã không được quản lý. –

+0

Tôi không tin rằng điều này không hoạt động nếu thực thi không phải là một ứng dụng .NET. Ví dụ, IIS quay lên các quy trình công nhân (w3wp.exe) là các thực thi không được quản lý mà nội bộ quay lên một thể hiện của CLR thực thi mã được quản lý. Nếu bạn sử dụng điều này từ bên trong mã được quản lý, tôi không tin rằng bạn sẽ nhận được đường dẫn đến w3wp.exe. –

40

Ngoài các câu trả lời ở trên.

tôi đã viết test.exe sau đây là giao diện điều khiển ứng dụng

static void Main(string[] args) { 
    Console.WriteLine(
    System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); 
    Console.WriteLine(
    System.Reflection.Assembly.GetEntryAssembly().Location); 
    Console.WriteLine(
    System.Reflection.Assembly.GetExecutingAssembly().Location); 
    Console.WriteLine(
    System.Reflection.Assembly.GetCallingAssembly().Location); 
} 

Sau đó, tôi biên soạn dự án và đổi tên sản lượng của nó vào file test2.exe. Các dòng đầu ra là chính xác và giống nhau.

Nhưng, nếu tôi bắt đầu nó trong Visual Studio, kết quả là:

d: \ test2.vhost.exe

d: \ test2.exe

d: \ test2.exe

C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ mscorlib.dll

Trình cắm thêm ReSharper vào Visual Studio đã gạch chân

System.Diagnostics.Process.GetCurrentProcess().MainModule 

làm hệ thống có thể.Ngoại lệ tham khảo. Nếu bạn nhìn vào tài liệu của MainModule, bạn sẽ thấy rằng thuộc tính này có thể ném cả NotSupportedException, PlatformNotSupportedException và InvalidOperationException.

Phương pháp GetEntryAssembly cũng không an toàn 100%. MSDN:

Phương pháp GetEntryAssembly có thể trở lại null khi một hội đồng quản lý đã được tải từ một ứng dụng không được quản lý. Ví dụ: nếu ứng dụng không được quản lý tạo một phiên bản của thành phần COM được viết bằng trong C#, lệnh gọi phương thức GetEntryAssembly từ thành phần C# trả về null, vì điểm nhập cho quá trình không được quản lý mã chứ không phải là hội đồng được quản lý .

Đối với các giải pháp của tôi, tôi thích Assembly.GetEntryAssembly().Location.

Sở thích khác là cần giải quyết vấn đề cho việc ảo hóa . Ví dụ, chúng ta có một dự án, trong đó chúng ta sử dụng một Postococode Postbuild để liên kết mã .net thành một tệp thực thi. Tệp thi hành này phải được đổi tên. Vì vậy, tất cả các phương pháp trên không hoạt động, bởi vì chúng chỉ nhận được thông tin cho quá trình lắp ráp ban đầu hoặc bên trong.

Giải pháp duy nhất tôi thấy là

var location = System.Reflection.Assembly.GetEntryAssembly().Location; 
var directory = System.IO.Path.GetDirectoryName(location); 
var file = System.IO.Path.Combine(directory, 
    System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"); 
+1

Phương thức GetEntryAssembly cũng trả về null nếu bạn đang chạy một ứng dụng dịch vụ WCF trong chế độ gỡ lỗi, dưới IIS. Đây là, phải thừa nhận rằng, một tình huống hiếm hoi mà chỉ có một nhà phát triển sẽ gặp phải. – Contango

+0

Assembly.GetEntryAssembly() là null cho tôi, khi tôi sử dụng Addin VS 2008. System.Diagnostics.Process.GetCurrentProcess().MainModule là devenv.exe, nhưng không phải DLL của tôi với Addin. và tôi không biết có được hội (của Addin) từ một hội đồng khác sử dụng addin. – Kiquenet

+0

1) Nếu A.exe sử dụng B.dll và B.dll sử dụng C.dll, điều gì xảy ra nếu mã đó nằm trong C.dll?. 2) AppDomain có thể là ứng dụng EXE, ứng dụng web, ứng dụng thử nghiệm đơn vị, Addin Visual Studio và "Ứng dụng Silverlight" (?). Có lẽ giải pháp đầy đủ thú vị cho mọi trường hợp. – Kiquenet

2

Cái này không bao gồm:

System.Windows.Forms.Application.ExecutablePath; 

~ Joe

+1

Nó dường như luôn luôn câm lặng với tôi rằng không gian tên Biểu mẫu có lớp Ứng dụng đó ... nó hoàn toàn không liên quan đến Biểu mẫu. – Nyerguds

+0

LOL - yeah, tôi cũng không sử dụng nó. Điểm lẻ để tìm nó. – jp2code

+4

Trên thực tế, lớp Ứng dụng độc quyền liên quan đến Biểu mẫu, trong đó phương thức Application.Run là những gì khởi tạo vòng lặp thông điệp cửa sổ chính xử lý tất cả các sự kiện cửa sổ (a.k.a. "form"). Nó cũng chứa DoEvents() cho phép cửa sổ xử lý các sự kiện đang chờ xử lý trong khi bên trong một trình xử lý. Điều này tất cả nên quen thuộc với bất cứ ai lập trình API Win32 trước khi phát minh ra .NET. – Triynko

8

Environment.GetCommandLineArgs() [0]

Các vấn đề liên quan