Cómo obtener la ruta de la carpeta para la aplicación ClickOnce

160

Necesito escribir un archivo en la misma carpeta donde reside una consola ClickOnce .application(archivo ejecutable). La carpeta desde donde se inicia.

Intenté usar Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) pero la ruta apunta a una subcarpeta debajo c:\Documents & Settings. ¿Cómo obtengo el camino donde .applicationreside el?

Tony_Henrich
fuente

Respuestas:

253

Para encontrar la ubicación de la carpeta, simplemente puede ejecutar la aplicación, abrir el administrador de tareas (CTRL-SHIFT-ESC), seleccionar la aplicación y hacer clic con el botón derecho | Abrir ubicación del archivo.

Erik Vullings
fuente
3
¡Hola, consejo profesional! pero no está disponible en máquinas viejas con XP desagradable. :)
Jalal
55
@Jalal para "máquinas viejas", visite www.SysInternals.com y descargue Process Explorer. Sospecho que los cambios en el Administrador de tareas de Win7 y luego Win8 simplemente se copiaron de él.
Arioch 'The
1
¿Cómo logra esto en su aplicación que se ejecuta en la computadora del cliente?
user3285954
2
¿Qué sucede si no puedo ejecutar la aplicación porque eliminaría un archivo de registro que necesito desesperadamente?
Tomáš Zato - Restablece a Monica el
2
@Tony_Henrich usted debe marcar esto como la respuesta correcta
sparkyShorts
120

la ruta apunta a una subcarpeta en c: \ Documents & Settings

Así es. ClickOnce applicationsse instalan bajo el perfil del usuario que los instaló. ¿Tomó el camino que le proporcionó la recuperación de la información del ensamblaje en ejecución y lo comprobó?

En Windows Vista y Windows 7, encontrará la caché ClickOnce aquí:

c:\users\username\AppData\Local\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

En Windows XP, lo encontrará aquí:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername
RobinDotNet
fuente
1
Entiendo todo esto. Quiero la carpeta desde donde hice clic en la aplicación. No tengo acceso a C: \ Documents and Settings, por lo tanto, no tendré acceso al archivo de registro si voy a usar la ruta de la carpeta devuelta por esa función y no quiero usar valores de ruta codificados .
Tony_Henrich
25

ApplicationDeployment.CurrentDeployment.ActivationUri podría funcionar

"Una cadena de longitud cero si la propiedad TrustUrlParameters en el manifiesto de implementación es falsa, o si el usuario ha proporcionado un UNC para abrir la implementación o la ha abierto localmente. De lo contrario, el valor de retorno es la URL completa utilizada para iniciar la aplicación, incluyendo cualquier parámetro ".


PERO lo que creo que realmente quieres es ApplicationDeployment.CurrentDeployment.DataDirectory que te da una carpeta en la que puedes escribir datos. De todos modos, cuando actualice la aplicación, perderá lo que estaba en la carpeta .exe original, pero puede migrar el directorio de datos a una nueva versión de la aplicación. Su aplicación puede escribir en esta carpeta con cualquier archivo de registro que tenga, y estoy bastante seguro de que se garantiza que se puede escribir.

Simon_Weaver
fuente
No hice nada, pero los archivos del antiguo DataDirectory se copian automáticamente al nuevo DataDirectory después de la implementación. No hay directorios .pre también. (.NET Framework 3.5 y 4.5)
Der_Meister
15

Estoy usando Assembly.GetExecutingAssembly().Locationpara obtener la ruta a una ClickOnceaplicación implementada en .Net 4.5.1.

Sin embargo, no debe escribir en ninguna carpeta en la que se haya implementado su aplicación, independientemente del método de implementación (xcopy, ClickOnce, InstallShield, cualquier cosa) porque generalmente se leen solo para aplicaciones, especialmente en las versiones más recientes de Windows y entornos de servidor.

Una aplicación siempre debe escribir en las carpetas reservadas para tales fines. Puede obtener las carpetas que necesita a partir de Environment.SpecialFolder Enumeration. La página de MSDN explica para qué sirve cada carpeta: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Es decir, para datos, registros y otros archivos que uno puede usar ApplicationData(roaming), LocalApplicationData(local) o CommonApplicationData. Para archivos temporales use Path.GetTempPatho Path.GetTempFileName.

Lo anterior también funciona en servidores y escritorios.

EDITAR: Assembly.GetExecutingAssembly()se llama en el ejecutable principal.

usuario3285954
fuente
Esto ha estado funcionando para mí para una aplicación ClickOnce, así como también en el entorno de desarrollo de VS mientras se depura esa misma aplicación.
Desarrollador63
3

Aplicaciones ClickOnce DO residen en un subdirectorio del directorio C: \ Documents y parámetros de configuración. No tienen directorios de instalación "limpios" porque los archivos locales se descargan esencialmente "temporalmente" para permitir que la aplicación se ejecute en la PC local y la ejecución de la aplicación se controla desde el servidor ClickOnce en el que se implementan según la configuración de publicación (Comprobación de actualizaciones, requisitos de versión, etc.).

NebuSoft
fuente
No tengo acceso a la carpeta C: \ Documents & Settings en el servidor, lo que significa que no tengo acceso al archivo que crea la aplicación. Ejecuto la aplicación desde una carpeta determinada. Es la carpeta donde se publica la aplicación. ¿Cómo obtengo la ruta de esa carpeta?
Tony_Henrich
Oh, quieres la URL de implementación. Lo siento, no entendí eso en absoluto. ¿Está tratando de obtenerlo desde la aplicación ClickOnce o desde una aplicación externa?
RobinDotNet
1

Esto es lo que encontré que funcionó para poder obtener la ubicación de la carpeta desplegada de mi aplicación clickonce y que no se ha mencionado en ningún lugar que vi en mis búsquedas, para mi escenario similar y específico:

  • La aplicación clickonce se implementa en una carpeta de red LAN de la empresa.
  • La aplicación clickonce está configurada para estar disponible en línea o fuera de línea.
  • Mi URL de instalación de clickonce y las URL de actualización en las propiedades de mi proyecto no tienen nada especificado. Es decir, no hay una ubicación separada para la instalación o las actualizaciones.
  • En mis opciones de publicación, tengo un acceso directo de escritorio creado para la aplicación clickonce.
  • La carpeta para la que quiero obtener la ruta al inicio es aquella a la que quiero que accedan las versiones DEV, INT y PROD de la aplicación, sin codificar la ruta.

Aquí hay una imagen de mi caso de uso:

ingrese la descripción de la imagen aquí

  • Las carpetas en recuadro azul son mis ubicaciones de directorio para la aplicación de cada entorno.
  • La carpeta en recuadro rojo es el directorio para el que quiero obtener la ruta (que requiere primero obtener la ubicación de la carpeta desplegada de la aplicación "MyClickOnceGreatApp_1_0_0_37", que es lo mismo que el OP).

No encontré ninguna de las sugerencias en esta pregunta o sus comentarios para trabajar en la devolución de la carpeta en la que se implementó la aplicación clickonce (que luego movería en relación con esta carpeta para encontrar la carpeta de interés). Ninguna otra búsqueda en Internet o preguntas relacionadas con SO tampoco dieron una respuesta.

Todas las propiedades sugeridas fallaban debido a que el objeto (por ejemplo, ActivationUri) era nulo o apuntaban a la carpeta de la aplicación instalada en caché de la PC local. Sí, podría manejar con gracia los objetos nulos mediante una comprobación de IsNetworkDeployed, eso no es un problema, pero sorprendentemente IsNetworkDeployed devuelve falso aunque de hecho tengo una ubicación de carpeta desplegada en la red para la aplicación clickonce. Esto se debe a que la aplicación se ejecuta desde los bits locales en caché.

La solución es mirar:

  • AppDomain.CurrentDomain.BaseDirectory cuando la aplicación se ejecuta en Visual Studio a medida que desarrollo y
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation cuando se ejecuta normalmente.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationdevuelve correctamente el directorio de red en el que se implementa mi aplicación clickonce, en todos los casos. Es decir, cuando se inicia a través de:

  • setup.exe
  • MyClickOnceGreatApp.application
  • El acceso directo de escritorio creado en la primera instalación e inicio de la aplicación.

Aquí está el código que uso al iniciar la aplicación para obtener la ruta de la carpeta WorkAccounts. Obtener la carpeta de la aplicación implementada es simple simplemente no avanzando hacia los directorios principales:

string directoryOfInterest = "";
if (System.Diagnostics.Debugger.IsAttached)
{
    directoryOfInterest = Directory.GetParent(Directory.GetParent(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName).FullName).FullName;
}
else
{
    try
    {
        string path = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
        path = path.Replace("file:", "");
        path = path.Replace("/", "\\");
        directoryOfInterest = Directory.GetParent(Directory.GetParent(path).FullName).FullName;
    }
    catch (Exception ex)
    {
        directoryOfInterest = "Error getting update directory needed for relative base for finding WorkAccounts directory.\n" + ex.Message + "\n\nUpdate location directory is: " + System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
    }
}
Kent Kruckeberg
fuente
0

Asumiendo que la pregunta es sobre el acceso a los archivos en la carpeta de la aplicación después de que la aplicación ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) está instalada en la PC del usuario, existen tres formas de obtener esta carpeta mediante la aplicación en sí:

String path1 = System.AppDomain.CurrentDomain.BaseDirectory;
String path2 = System.IO.Directory.GetCurrentDirectory();    
String path3 = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; //Remove the last path component, the executing assembly itself.

Estos funcionan desde VS IDE y desde una aplicación ClickedOnce implementada / instalada, no se requiere verificación "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed". ClickOnce recoge los archivos incluidos en el proyecto Visual Studio 2017 para que realmente la aplicación pueda acceder a todos los archivos implementados utilizando rutas relativas desde dentro de la aplicación.

Esto se basa en Windows 10 y Visual Studio 2017

BoiseBaked
fuente