Comment obtenir le chemin du dossier pour l'application ClickOnce

160

J'ai besoin d'écrire un fichier dans le même dossier où réside une console ClickOnce .application(fichier exécutable). Le dossier à partir duquel il est lancé.

J'ai essayé d'utiliser Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) mais le chemin pointe vers un sous-dossier sous c:\Documents & Settings. Comment puis-je obtenir le chemin où .applicationréside le?

Tony_Henrich
la source

Réponses:

253

Pour trouver l'emplacement du dossier, vous pouvez simplement exécuter l'application, ouvrir le gestionnaire de tâches (CTRL-SHIFT-ESC), sélectionner l'application et faire un clic droit | Ouvrir l'emplacement du fichier.

Erik Vullings
la source
3
hé, conseil de pro! mais il n'est pas disponible sur les vieilles machines XP de merde. :)
Jalal
5
@Jalal pour les «vieilles machines de merde», allez sur www.SysInternals.com et téléchargez Process Explorer. Je soupçonne que les changements dans TaskManager de Win7 puis Win8 ont été copiés à partir de celui-ci.
Arioch 'The
1
Comment y parvenir dans votre application exécutée sur l'ordinateur du client?
user3285954
2
Que faire si je ne peux pas exécuter l'application car cela supprimerait un fichier journal dont j'ai désespérément besoin?
Tomáš Zato - Réintégrer Monica
2
@Tony_Henrich vous devriez marquer ceci comme la bonne réponse
sparkyShorts
120

le chemin pointe vers un sous-dossier sous c: \ Documents & Settings

C'est vrai. ClickOnce applicationssont installés sous le profil de l'utilisateur qui les a installés. Avez-vous emprunté le chemin que vous a donné la récupération des informations de l'assembly en cours d'exécution et êtes-vous allé le vérifier?

Sur Windows Vista et Windows 7, vous trouverez le cache ClickOnce ici:

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

Sous Windows XP, vous le trouverez ici:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername
RobinDotNet
la source
1
Je comprends tout cela. Je veux le dossier à partir duquel j'ai cliqué sur l'application. Je n'ai pas accès aux C: \ Documents and Settings, donc je n'aurai pas accès au fichier journal si je vais utiliser le chemin du dossier retourné par cette fonction et je ne veux pas utiliser de valeurs de chemin codées en dur .
Tony_Henrich
25

ApplicationDeployment.CurrentDeployment.ActivationUri peut fonctionner

"Une chaîne de longueur nulle si la propriété TrustUrlParameters dans le manifeste de déploiement est false, ou si l'utilisateur a fourni un UNC pour ouvrir le déploiement ou l'a ouvert localement. Sinon, la valeur renvoyée est l'URL complète utilisée pour lancer l'application, y compris tous les paramètres. "


MAIS ce que je pense que vous voulez vraiment, c'est ApplicationDeployment.CurrentDeployment.DataDirectory qui vous donne un dossier dans lequel vous pouvez écrire des données. Lorsque vous mettez à jour l'application de toute façon, vous perdez ce qui se trouvait dans le dossier .exe d'origine, mais vous pouvez migrer le répertoire de données vers une nouvelle version de l'application. Votre application peut écrire dans ce dossier avec tous les fichiers journaux dont elle dispose - et je suis à peu près sûr que son écriture est garantie.

Simon_Weaver
la source
Je n'ai rien fait, mais les fichiers de l'ancien DataDirectory sont automatiquement copiés dans le nouveau DataDirectory après le déploiement. Il n'y a pas non plus de répertoires .pre. (.NET Framework 3.5 et 4.5)
Der_Meister
15

J'utilise Assembly.GetExecutingAssembly().Locationpour obtenir le chemin vers une ClickOnceapplication déployée dans .Net 4.5.1.

Cependant, vous ne devez écrire dans aucun dossier dans lequel votre application est déployée, quelle que soit la méthode de déploiement (xcopy, ClickOnce, InstallShield, quoi que ce soit), car ceux-ci sont généralement en lecture seule pour les applications, en particulier dans les nouvelles versions de Windows et les environnements de serveur.

Une application doit toujours écrire dans les dossiers réservés à ces fins. Vous pouvez obtenir les dossiers dont vous avez besoin à partir de Environment.SpecialFolder Enumeration. La page MSDN explique à quoi sert chaque dossier: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

C'est-à-dire pour les données, les journaux et autres fichiers que l'on peut utiliser ApplicationData(itinérance), LocalApplicationData(local) ou CommonApplicationData. Pour les fichiers temporaires, utilisez Path.GetTempPathou Path.GetTempFileName.

Les éléments ci-dessus fonctionnent également sur les serveurs et les ordinateurs de bureau.

EDIT: Assembly.GetExecutingAssembly()est appelé dans l'exécutable principal.

user3285954
la source
Cela a fonctionné pour moi pour une application ClickOnce, ainsi que dans l'environnement de développement VS tout en déboguant cette même application.
Developer63
3

Applications ClickOnce DO résident dans un sous - répertoire C: \ Documents & Settings. Ils n'ont pas de répertoires d'installation «propres» car les fichiers locaux sont essentiellement téléchargés «temporairement» pour permettre à l'application de s'exécuter sur le PC local et l'exécution de l'application est contrôlée à partir du serveur ClickOnce sur lequel ils sont déployés en fonction des paramètres de publication. (Vérification des mises à jour, des exigences de version, etc.).

NebuSoft
la source
Je n'ai pas accès au dossier C: \ Documents & Settings sur le serveur, ce qui signifie que je n'ai pas accès au fichier créé par l'application. J'exécute l'application à partir d'un certain dossier. C'est le dossier dans lequel l'application est publiée. Comment obtenir le chemin de ce dossier?
Tony_Henrich
Oh, vous voulez l'URL de déploiement. Désolé, je n'ai pas du tout compris. Essayez-vous de l'obtenir depuis l'application ClickOnce ou depuis une application externe?
RobinDotNet
1

Voici ce que j'ai trouvé qui a fonctionné pour pouvoir obtenir l'emplacement du dossier déployé de mon application clickonce et qui n'a été mentionné nulle part dans mes recherches, pour mon scénario similaire et spécifique:

  • L'application clickonce est déployée dans un dossier réseau LAN d'entreprise.
  • L'application clickonce est définie pour être disponible en ligne ou hors ligne.
  • L'URL d'installation ClickOne et les URL de mise à jour dans les propriétés de mon projet n'ont rien de spécifié. Autrement dit, il n'y a pas d'emplacement séparé pour l'installation ou les mises à jour.
  • Dans mes options de publication, j'ai créé un raccourci sur le bureau pour l'application ClickOne.
  • Le dossier dont je souhaite obtenir le chemin au démarrage est celui auquel je souhaite accéder par les versions DEV, INT et PROD de l'application, sans codage en dur du chemin.

Voici un visuel de mon cas d'utilisation:

entrez la description de l'image ici

  • Les dossiers encadrés bleus sont mes emplacements de répertoire pour l'application de chaque environnement.
  • Le dossier encadré rouge est le répertoire pour lequel je veux obtenir le chemin (ce qui nécessite d'abord d'obtenir l'emplacement du dossier déployé de l'application "MyClickOnceGreatApp_1_0_0_37" qui est le même que l'OP).

Je n'ai trouvé aucune des suggestions de cette question ou de leurs commentaires pour retourner le dossier dans lequel l'application clickonce a été déployée (que je déplacerais ensuite par rapport à ce dossier pour trouver le dossier d'intérêt). Aucune autre recherche sur Internet ni aucune question relative à l'OS n'a donné de réponse.

Toutes les propriétés suggérées échouaient en raison de la nullité de l'objet (par exemple ActivationUri) ou pointaient vers le dossier d'application installée en cache du PC local. Oui, je pourrais gérer gracieusement les objets nuls en vérifiant IsNetworkDeployed - ce n'est pas un problème - mais, étonnamment, IsNetworkDeployed renvoie false même si j'ai en fait un emplacement de dossier déployé sur le réseau pour l'application clickonce. En effet, l'application s'exécute à partir des bits locaux mis en cache.

La solution est de regarder:

  • AppDomain.CurrentDomain.BaseDirectory lorsque l'application est exécutée dans Visual Studio pendant que je développe et
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation lorsqu'il s'exécute normalement.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationrenvoie correctement le répertoire réseau dans lequel mon application clickonce est déployée, dans tous les cas. Autrement dit, lorsqu'il est lancé via:

  • setup.exe
  • MyClickOnceGreatApp.application
  • Le raccourci sur le bureau créé lors de la première installation et du premier lancement de l'application.

Voici le code que j'utilise au démarrage de l'application pour obtenir le chemin du dossier WorkAccounts. Obtenir le dossier d'application déployé est simple en ne se dirigeant pas vers les répertoires parents:

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
la source
0

En supposant que la question porte sur l'accès aux fichiers dans le dossier de l'application après que l'application ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) est installée sur le PC de l'utilisateur, il existe trois façons d'obtenir ce dossier par l'application elle-même:

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.

Ceux-ci fonctionnent à partir de VS IDE et d'une application ClickedOnce déployée / installée, aucune vérification "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed" n'est requise. ClickOnce récupère tous les fichiers inclus dans le projet Visual Studio 2017 afin que l'application puisse vraiment accéder à tous les fichiers déployés à l'aide de chemins relatifs à partir de l'application.

Ceci est basé sur Windows 10 et Visual Studio 2017

Boise au four
la source