.net - software - ruta critica secundaria
Cómo obtener la ruta de la carpeta para la aplicación ClickOnce (7)
Necesito escribir un archivo en la misma carpeta donde reside una consola ClickOnce .application
(archivo ejecutable). La carpeta desde donde se lanza.
Intenté usar Application.StartupPath
& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
pero la ruta apunta a una subcarpeta en c:/Documents & Settings
. ¿Cómo obtengo la ruta en la que reside la aplicación .application
?
ruta está apuntando a una subcarpeta en c: / Documents & Settings
Está bien. ClickOnce applications
se instalan bajo el perfil del usuario que las instaló. ¿Tomó el camino que le dio la recuperación de la información del ensamblaje en ejecución y lo revisó?
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ás aquí:
C:/Documents and Settings/username/LocalSettings/Apps/2.0/obfuscatedfoldername/obfuscatedfoldername
Después de una búsqueda exhaustiva, finalmente encontré una forma de encontrar los nombres de las carpetas ofuscadas a través del registro. Aquí hay un método simple para obtenerlos:
private static Tuple<string, string> GetClickonceDirectories()
{
var appToken = (string) Registry.GetValue(@"HKEY_CURRENT_USER/SOFTWARE/Classes/Software/Microsoft/Windows/CurrentVersion/Deployment/SideBySide/2.0", "ComponentStore_RandomString", null);
var dataToken = (string) Registry.GetValue(@"HKEY_CURRENT_USER/SOFTWARE/Classes/Software/Microsoft/Windows/CurrentVersion/Deployment/SideBySide/2.0/StateManager", "StateStore_RandomString", null);
if (string.IsNullOrWhiteSpace(appToken) || string.IsNullOrWhiteSpace(dataToken))
{
throw new Exception("Unable to find clickonce directories.");
}
var appDir =
$@"{appToken.Substring(0, 8)}.{appToken.Substring(8, 3)}/{appToken.Substring(11, 8)}.{appToken.Substring(19, 3)}";
var dataDir =
$@"Data/{dataToken.Substring(0, 8)}.{dataToken.Substring(8, 3)}/{dataToken.Substring(11, 8)}.{dataToken.Substring(19, 3)}";
var rootPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
rootPath = Path.Combine(rootPath, "Apps", "2.0");
return new Tuple<string, string>(Path.Combine(rootPath, appDir), Path.Combine(rootPath, dataDir));
}
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 ninguna parte que vi en mis búsquedas, para mi escenario específico similar:
- La aplicación clickonce se implementa en la carpeta de red LAN de una 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 acceder mediante las versiones DEV, INT y PROD de la aplicación, sin tener que codificar en la ruta.
Aquí hay una vista visual de mi caso de uso:
- 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 donde quiero obtener la ruta (que requiere primero obtener la ubicación de la carpeta implementada 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 que funcionen al devolver 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 aparecieron una respuesta tampoco.
Todas las propiedades sugeridas estaban fallando 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 objetos nulos con un cheque 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 está ejecutando normalmente.
System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation
devuelve correctamente el directorio de red en el que se implementa mi aplicación Clickonce, en todos los casos. Es decir, cuando se lanza a través de:
- setup.exe
- MyClickOnceGreatApp.application
- El acceso directo de escritorio creado en la primera instalación y el inicio de la aplicación.
Aquí está el código que uso al inicio de la aplicación para obtener la ruta de la carpeta WorkAccounts. Obtener la carpeta de la aplicación desplegada es simple simplemente no marchar hasta 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();
}
}
Estoy usando Assembly.GetExecutingAssembly().Location
para obtener la ruta a una aplicación desplegada ClickOnce
en .Net 4.5.1.
Sin embargo, no debe escribir en ninguna carpeta donde se implemente su aplicación para siempre, independientemente del método de implementación (xcopy, ClickOnce, InstallShield, etc.) ya que normalmente solo se leen para aplicaciones, especialmente en versiones de Windows y entornos de servidor más nuevos.
Una aplicación siempre debe escribir en las carpetas reservadas para tales fines. Puede obtener las carpetas que necesita desde Environment.SpecialFolder Enumeration. La página de MSDN explica para qué es cada carpeta: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx
Es decir, para datos, registros y otros archivos, uno puede usar ApplicationData
(roaming), LocalApplicationData
(local) o CommonApplicationData
. Para los archivos temporales, use Path.GetTempPath
o Path.GetTempFileName
.
El trabajo anterior en servidores y escritorios también.
EDITAR: Assembly.GetExecutingAssembly()
se llama en el ejecutable principal.
Las aplicaciones ClickOnce DO residen en un subdirectorio de C: / Documents & Settings. No tienen directorios de instalación "limpios" porque los archivos locales se descargan "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 están implementados, dependiendo de la configuración de publicación. (Comprobación de actualizaciones, requisitos de versión, etc.).
Para encontrar la ubicación de la carpeta, solo 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 en Abrir la ubicación del archivo.
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 el despliegue o lo ha abierto localmente. De lo contrario, el valor devuelto es el URL completo utilizado para iniciar la aplicación, incluyendo cualquier parámetro ".
PERO lo que realmente quiero es ApplicationDeployment.CurrentDeployment.DataDirectory que le proporciona una carpeta en la que puede escribir datos. Cuando actualice la aplicación de todos modos, 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 seguro de que se puede escribir.