Come ottenere il percorso della cartella per l'applicazione ClickOnce


160

Devo scrivere un file nella stessa cartella in cui risiede una console ClickOnce .application(file eseguibile). La cartella da cui viene avviata.

Ho provato a usare Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ma il percorso punta a una sottocartella sotto c:\Documents & Settings. Come posso ottenere il percorso in cui .applicationrisiede?

Risposte:


253

Per trovare la posizione della cartella, puoi semplicemente eseguire l'app, aprire il task manager (CTRL-SHIFT-ESC), selezionare l'app e fare clic con il tasto destro del mouse su | Apri posizione file.


3
ehi, consiglio pro! ma non è disponibile su vecchie macchine XP scadenti. :)
Jalal il

5
@Jalal per "vecchie macchine scadenti" vai su www.SysInternals.com e scarica Process Explorer. Sospetto che le modifiche in TaskManager di Win7 e Win8 siano state appena copiate da esso.
Arioch "Il

1
Come si ottiene questo risultato nella propria applicazione in esecuzione sul computer del cliente?
user3285954

2
Cosa succede se non riesco a eseguire l'applicazione perché eliminerebbe un file di registro di cui ho un disperato bisogno?
Tomáš Zato - Ripristina Monica il

2
@Tony_Henrich dovresti contrassegnarlo come la risposta corretta
sparkyShorts

120

il percorso punta a una sottocartella in c: \ Documents & Settings

Giusto. ClickOnce applicationssono installati sotto il profilo dell'utente che li ha installati. Hai seguito il percorso che ti ha fornito il recupero delle informazioni dall'assembly in esecuzione e sei andato a provarlo?

Su Windows Vista e Windows 7, troverai la cache ClickOnce qui:

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

Su Windows XP, lo troverai qui:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

1
Capisco tutto questo. Voglio la cartella da cui ho fatto clic sull'app. Non ho accesso a C: \ Documents and Settings, pertanto non avrò accesso al file di registro se intendo utilizzare il percorso della cartella restituito da quella funzione e non desidero utilizzare valori di percorso codificati .
Tony_Henrich

25

ApplicationDeployment.CurrentDeployment.ActivationUri potrebbe funzionare

"Una stringa di lunghezza zero se la proprietà TrustUrlParameters nel manifest di distribuzione è falsa o se l'utente ha fornito un UNC per aprire la distribuzione o l'ha aperta localmente. In caso contrario, il valore restituito è l'URL completo utilizzato per avviare l'applicazione, compresi eventuali parametri ".


MA quello che penso tu voglia davvero è ApplicationDeployment.CurrentDeployment.DataDirectory che ti dà una cartella in cui puoi scrivere i dati. Quando aggiorni l'applicazione perdi comunque ciò che era nella cartella .exe originale, ma puoi migrare la directory dei dati su una nuova versione dell'app. La tua app può scrivere in questa cartella con qualsiasi file di registro abbia - e sono quasi sicuro che sia garantita la scrittura.


Non ho fatto nulla, ma i file della vecchia DataDirectory vengono automaticamente copiati nella nuova DataDirectory dopo la distribuzione. Non ci sono anche directory .pre. (.NET Framework 3.5 e 4.5)
Der_Meister

15

Sto usando Assembly.GetExecutingAssembly().Locationper ottenere il percorso di ClickOnceun'applicazione distribuita in .Net 4.5.1.

Tuttavia, non dovresti scrivere in nessuna cartella in cui la tua applicazione viene mai distribuita, indipendentemente dal metodo di distribuzione (xcopy, ClickOnce, InstallShield, qualsiasi cosa) perché quelli sono di solito letti solo per le applicazioni, specialmente nelle nuove versioni di Windows e negli ambienti server.

Un'app deve sempre scrivere nelle cartelle riservate a tali scopi. È possibile ottenere le cartelle necessarie a partire dall'enumerazione Environment.SpecialFolder. La pagina MSDN spiega a cosa serve ogni cartella: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Vale a dire per dati, registri e altri file che è possibile utilizzare ApplicationData(roaming), LocalApplicationData(locale) o CommonApplicationData. Per i file temporanei utilizzare Path.GetTempPatho Path.GetTempFileName.

Quanto sopra funziona anche su server e desktop.

EDIT: Assembly.GetExecutingAssembly()viene chiamato nell'eseguibile principale.


Questo ha funzionato per me per un'app ClickOnce, oltre a funzionare nell'ambiente di sviluppo VS durante il debug della stessa app.
Developer63,

3

Applicazioni ClickOnce DO risiedono in una sottodirectory di C: \ Documenti e Impostazioni. Non hanno directory di installazione "pulite" perché i file locali vengono essenzialmente scaricati "temporaneamente" per consentire l'esecuzione dell'applicazione sul PC locale e l'esecuzione dell'applicazione è controllata dal server ClickOnce su cui sono distribuiti a seconda delle impostazioni di pubblicazione (Verifica di aggiornamenti, requisiti di versione, ecc.).


Non ho accesso alla cartella C: \ Documents & Settings sul server, il che significa che non ho accesso al file creato dall'app. Eseguo l'app da una determinata cartella. È la cartella in cui è pubblicata l'app. Come posso ottenere il percorso di quella cartella?
Tony_Henrich

Oh, vuoi l'URL di distribuzione. Mi dispiace, non l'ho capito affatto. Stai cercando di ottenerlo dall'interno dell'applicazione ClickOnce o da un'applicazione esterna?
RobinDotNet

1

Ecco cosa ho scoperto che ha funzionato per essere in grado di ottenere il percorso della cartella distribuita della mia applicazione clickonce e che non è stato menzionato da nessuna parte che ho visto nelle mie ricerche, per il mio scenario simile e specifico:

  • L'applicazione clickonce viene distribuita in una cartella di rete LAN aziendale.
  • L'applicazione clickonce è impostata per essere disponibile online o offline.
  • L'URL di installazione di Clickonce e gli URL di aggiornamento nelle proprietà del mio progetto non hanno specificato nulla. Cioè, non esiste un percorso separato per l'installazione o gli aggiornamenti.
  • Nelle mie opzioni di pubblicazione, sto avendo un collegamento sul desktop creato per l'applicazione clickonce.
  • La cartella per cui voglio ottenere il percorso all'avvio è quella a cui voglio accedere dalle versioni DEV, INT e PROD dell'applicazione, senza codificare il percorso.

Ecco un'immagine del mio caso d'uso:

inserisci qui la descrizione dell'immagine

  • Le cartelle blue box sono le posizioni delle mie directory per ciascuna applicazione di ambiente.
  • La cartella in scatola rossa è la directory per cui voglio ottenere il percorso (che richiede innanzitutto ottenere la posizione della cartella distribuita dell'app "MyClickOnceGreatApp_1_0_0_37" che è la stessa dell'OP).

Non ho trovato alcun suggerimento in questa domanda o i loro commenti per funzionare nel restituire la cartella in cui è stata distribuita l'applicazione clickonce (che poi vorrei spostare rispetto a questa cartella per trovare la cartella di interesse). Nemmeno altre ricerche su Internet o relative domande SO hanno dato una risposta.

Tutte le proprietà suggerite non funzionavano perché l'oggetto (ad esempio ActivationUri) era nullo o puntavano alla cartella dell'app installata nella cache del PC locale. Sì, ho potuto gestire con grazia oggetti null controllando IsNetworkDeployed - questo non è un problema - ma sorprendentemente IsNetworkDeployed restituisce false anche se in realtà ho una posizione di cartella distribuita in rete per l'applicazione clickonce. Questo perché l'applicazione è in esecuzione dai bit locali memorizzati nella cache.

La soluzione è guardare a:

  • AppDomain.CurrentDomain.BaseDirectory quando l'applicazione viene eseguita in Visual Studio mentre sviluppo e
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation quando si sta eseguendo normalmente.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationrestituisce correttamente la directory di rete in cui è distribuita la mia applicazione clickonce, in tutti i casi. Cioè, quando viene lanciato tramite:

  • setup.exe
  • MyClickOnceGreatApp.application
  • Il collegamento sul desktop creato alla prima installazione e avvio dell'applicazione.

Ecco il codice che utilizzo all'avvio dell'applicazione per ottenere il percorso della cartella WorkAccounts. Ottenere la cartella dell'applicazione distribuita è semplice semplicemente non marciando sulle directory principali:

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

0

Supponendo che la domanda riguardi l'accesso ai file nella cartella dell'applicazione dopo che l'applicazione ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) è installata sul PC dell'utente, sono tre i modi per ottenere questa cartella dall'applicazione stessa:

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.

Funzionano da VS IDE e da un'app ClickedOnce distribuita / installata, non è richiesto alcun controllo "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed". ClickOnce raccoglie tutti i file inclusi nel progetto Visual Studio 2017 in modo che l'applicazione possa davvero accedere a tutti i file distribuiti utilizzando percorsi relativi all'interno dell'applicazione.

Questo si basa su Windows 10 e Visual Studio 2017

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.