2009-06-11 7 views

Respuesta

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

Este tiende a agregar ".vhost". en el nombre de archivo, un problema no presente si se usa System.Reflection.Assembly.GetEntryAssembly(). Ubicación (ver respuesta alternativa). – Contango

+4

@Contango, que se produce al usar "Visual Studio Hosting Process" en VS. – LuddyPants

+0

Para pruebas unitarias en 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: \ ARCHIVOS DE PROGRAMA (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.executionengine.x86.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName : UnitTestAdapter: Running test – Kiquenet

7

creo que esto debería ser lo que quieres:

System.Reflection.Assembly.GetEntryAssembly().Location 

Esto devuelve el ensamblaje que se cargó por primera vez cuando se inició el proceso, que parecería ser lo que desea.

GetCallingAssembly no devolverá necesariamente el conjunto que desee en el caso general, ya que devuelve el conjunto que contiene el método inmediatamente superior en la pila de llamadas (es decir, podría estar en la misma DLL).

+0

estoy no estoy seguro acerca de GetCallingAssembly() - ¿no es cierto que devuelve el ensamblado que contiene el método de llamada (uno arriba en la pila de llamadas)? Es probable que sea la biblioteca en lugar del ejecutable. –

+0

@Martin: Sí, tienes razón. GetCallingAssembly puede funcionar/ser apropiado en algunos casos, pero parece que quiere GetEntryAssembly aquí. – Noldorin

3

Assembly.GetEntryAssembly()

70

Si desea que el ejecutable:

System.Reflection.Assembly.GetEntryAssembly().Location 

Si desea que la asamblea que está consumiendo su biblioteca (que podría ser el mismo conjunto que el anterior, si el código se llama directamente de una clase dentro de tu ejecutable):

System.Reflection.Assembly.GetCallingAssembly().Location 

Si quieres e sólo el archivo nombre y no el camino, el uso:

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

GetEntryAssembly podría devolver nulo si se llama desde código no administrado. –

+0

No creo que esto no funcione si el ejecutable no es una aplicación .NET. Por ejemplo, IIS genera procesos de trabajo (w3wp.exe) que son ejecutables no administrados que activan internamente una instancia del CLR que ejecuta el código administrado. Si usa esto desde dentro del código administrado, no creo que obtenga la ruta a w3wp.exe. –

40

Además de las respuestas anteriores.

escribí siguiente test.exe como aplicación de consola

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); 
} 

A continuación he recopilado el proyecto y renombró su salida al archivo test2.exe. Las líneas de salida fueron correctas y lo mismo.

Pero, si lo inicio en el Visual Studio, el resultado es:

d: \ test2.vhost.exe

d: \ test2.exe

d: \ test2.exe

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

El complemento ReSharper para Visual Studio ha subrayado el

System.Diagnostics.Process.GetCurrentProcess().MainModule 

como sistema posible.Excepcion de referencia nula. Si observa la documentación del MainModule, encontrará que esta propiedad también puede arrojar NotSupportedException, PlatformNotSupportedException y InvalidOperationException.

El método GetEntryAssembly tampoco es 100% "seguro". MSDN:

El método GetEntryAssembly puede volver nula cuando un ensamblado administrado se ha cargado desde una aplicación no administrado. Por ejemplo, si una aplicación no administrada crea una instancia de un componente COM escrito en C#, una llamada al método GetEntryAssembly del componente C# devuelve nulo, porque el punto de entrada para el proceso no fue administrado en lugar de un ensamblaje administrado .

Para mis soluciones, prefiero Assembly.GetEntryAssembly().Location.

Más interés es si necesita resolver el problema para la virtualización . Por ejemplo, tenemos un proyecto, donde usamos un Postbuild Xenocode para vincular el código .net en un ejecutable. Este ejecutable debe ser renombrado. Entonces, todos los métodos anteriores no funcionaron, porque solo obtienen la información para el ensamblaje original o el proceso interno.

La única solución que he encontrado es

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

El método GetEntryAssembly también devuelve nulo si está ejecutando una aplicación de servicio WCF en modo de depuración, en IIS. Esto es, sin duda, una situación rara que solo un desarrollador encontraría. – Contango

+0

Assembly.GetEntryAssembly() es nulo para mí, cuando utilizo Addin VS 2008. System.Diagnostics.Process.GetCurrentProcess().MainModule es devenv.exe, pero no es mi DLL con Addin. y no sé obtener la Asamblea (de Addin) de otra asamblea que use el complemento. – Kiquenet

+0

1) Si A.exe usa B.dll, y B.dll usa C.dll, ¿qué sucede si ese código está en C.dll? 2) AppDomain puede ser una aplicación EXE, aplicación web, aplicación de prueba unitaria, Addin Visual Studio y "aplicación Silverlight" (?). Tal vez una solución completa interesante para todos los casos. – Kiquenet

2

Ésta no se incluyó:

System.Windows.Forms.Application.ExecutablePath; 

~ Joe

+1

Siempre me pareció tonto que el espacio de nombres de Forms tuviera esa clase de aplicación ... no tiene ninguna relación con Forms. – Nyerguds

+0

LOL - Sí, yo tampoco lo uso. Lugar extraño para encontrarlo. – jp2code

+4

En realidad, la clase Application se relaciona exclusivamente con Forms, ya que el método Application.Run es el que inicia el ciclo de mensajes de la ventana principal que procesa todos los eventos de la ventana (a.k.a. "formulario"). También contiene DoEvents() que permite que la ventana procese eventos pendientes mientras está dentro de un controlador. Todo esto debería ser familiar para cualquiera que haya programado la API Win32 antes de la invención de .NET. – Triynko

8

Environment.GetCommandLineArgs() [0]

Cuestiones relacionadas