Jak uzyskać ścieżkę do folderu dla aplikacji ClickOnce

160

Muszę napisać plik w tym samym folderze, w którym znajduje się konsola ClickOnce .application(plik wykonywalny). Folder, z którego jest uruchamiany.

Próbowałem użyć Application.StartupPath&, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ale ścieżka wskazuje na podfolder pod c:\Documents & Settings. Jak uzyskać ścieżkę, w której .applicationmieszka?

Tony_Henrich
źródło

Odpowiedzi:

253

Aby znaleźć lokalizację folderu, możesz po prostu uruchomić aplikację, otworzyć menedżera zadań (CTRL-SHIFT-ESC), wybrać aplikację i kliknąć prawym przyciskiem myszy | Otwórz lokalizację pliku.

Erik Vullings
źródło
3
hej, profesjonalna wskazówka! ale nie jest dostępny na starych, kiepskich komputerach XP. :)
Jalal
5
@Jalal dla „starych, gównianych maszyn” wejdź na www.SysInternals.com i pobierz Process Explorer. Podejrzewam, że zmiany w TaskManagerze Win7, a następnie Win8 zostały właśnie z niego skopiowane.
Arioch „The
1
Jak to osiągnąć w aplikacji działającej na komputerze klienta?
user3285954
2
Co jeśli nie mogę uruchomić aplikacji, ponieważ usunęłaby ona plik dziennika, którego bardzo potrzebuję?
Tomáš Zato - Przywróć Monikę
2
@Tony_Henrich powinieneś oznaczyć to jako poprawną odpowiedź
sparkyShorts
120

ścieżka wskazuje na podfolder w katalogu c: \ Documents & Settings

Zgadza się. ClickOnce applicationssą instalowane w profilu użytkownika, który je zainstalował. Czy wybrałeś ścieżkę, którą dało ci pobranie informacji z zespołu wykonawczego i poszedłeś to sprawdzić?

W systemie Windows Vista i Windows 7 pamięć podręczną ClickOnce znajdziesz tutaj:

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

W systemie Windows XP znajdziesz go tutaj:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername
RobinDotNet
źródło
1
Rozumiem to wszystko. Chcę folderu, z którego kliknąłem aplikację. Nie mam dostępu do C: \ Documents and Settings, dlatego nie będę mieć dostępu do pliku dziennika, jeśli mam zamiar użyć ścieżki folderu zwróconej przez tę funkcję i nie chcę używać zakodowanych na stałe wartości ścieżki .
Tony_Henrich
25

ApplicationDeployment.CurrentDeployment.ActivationUri może działać

„Ciąg o zerowej długości, jeśli właściwość TrustUrlParameters w manifeście wdrożenia ma wartość false lub jeśli użytkownik podał UNC do otwarcia wdrożenia lub otworzył je lokalnie. W przeciwnym razie wartością zwracaną jest pełny adres URL używany do uruchomienia aplikacji, w tym wszelkie parametry. ”


ALE to, co myślę, że naprawdę chcesz, to ApplicationDeployment.CurrentDeployment.DataDirectory, który udostępnia folder, w którym możesz zapisywać dane. Po zaktualizowaniu aplikacji i tak utracisz zawartość oryginalnego folderu .exe, ale możesz przenieść katalog danych do nowej wersji aplikacji. Twoja aplikacja może zapisywać w tym folderze za pomocą dowolnych plików dziennika, które ma - i jestem prawie pewien, że gwarantuje on możliwość zapisu.

Simon_Weaver
źródło
Nic nie zrobiłem, ale pliki ze starego DataDirectory są automatycznie kopiowane do nowego DataDirectory po wdrożeniu. Nie ma również katalogów .pre. (.NET Framework 3.5 i 4.5)
Der_Meister,
15

Używam Assembly.GetExecutingAssembly().Locationdo uzyskania ścieżki do ClickOncewdrożonej aplikacji w .Net 4.5.1.

Jednak nie należy zapisywać w żadnym folderze, w którym aplikacja jest wdrażana, niezależnie od metody wdrażania (xcopy, ClickOnce, InstallShield, cokolwiek), ponieważ są one zwykle tylko do odczytu dla aplikacji, szczególnie w nowszych wersjach systemu Windows i środowiskach serwerowych.

Aplikacja musi zawsze zapisywać w folderach zarezerwowanych do takich celów. Możesz pobrać potrzebne foldery, zaczynając od Environment.SpecialFolder Enumeration. Strona MSDN wyjaśnia, do czego służy każdy folder: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Tj. Dane, logi i inne pliki, z których można korzystać ApplicationData(roaming), LocalApplicationData(lokalnie) lub CommonApplicationData. W przypadku plików tymczasowych użyj Path.GetTempPathlub Path.GetTempFileName.

Powyższe działa również na serwerach i komputerach stacjonarnych.

EDYCJA: Assembly.GetExecutingAssembly()jest wywoływana w głównym pliku wykonywalnym.

user3285954
źródło
Działa to w przypadku mnie w przypadku aplikacji ClickOnce, a także w środowisku programistycznym VS podczas debugowania tej samej aplikacji.
Deweloper
3

Aplikacji ClickOnce DO rezydować w podkatalogu C: \ Documents & Settings. Nie mają „czystych” katalogów instalacyjnych, ponieważ pliki lokalne są w zasadzie pobierane „tymczasowo”, aby umożliwić działanie aplikacji na lokalnym komputerze, a wykonywanie aplikacji jest kontrolowane z serwera ClickOnce, na którym są wdrażane, w zależności od ustawień publikowania (Sprawdzanie aktualizacji, wymagań dotyczących wersji itp.).

NebuSoft
źródło
Nie mam dostępu do folderu C: \ Documents & Settings na serwerze, co oznacza, że ​​nie mam dostępu do pliku utworzonego przez aplikację. Uruchamiam aplikację z określonego folderu. Jest to folder, w którym została opublikowana aplikacja. Jak uzyskać ścieżkę do tego folderu?
Tony_Henrich
Och, potrzebujesz adresu URL wdrożenia. Przepraszam, w ogóle tego nie rozumiem. Czy próbujesz pobrać go z poziomu aplikacji ClickOnce, czy z aplikacji zewnętrznej?
RobinDotNet
1

Oto, co znalazłem, co zadziałało, aby uzyskać lokalizację wdrożonego folderu mojej aplikacji Clickonce i nie zostało nigdzie wspomniane w moich wyszukiwaniach, dla mojego podobnego, konkretnego scenariusza:

  • Aplikacja Clickonce jest wdrażana w firmowym folderze sieci LAN.
  • Aplikacja Clickonce jest ustawiona jako dostępna online lub offline.
  • Mój adres URL instalacji Clickonce i adresy URL aktualizacji we właściwościach projektu nie mają nic określonego. Oznacza to, że nie ma oddzielnej lokalizacji do instalacji lub aktualizacji.
  • W moich opcjach publikowania mam utworzony skrót na pulpicie dla aplikacji Clickonce.
  • Folder, do którego chcę uzyskać ścieżkę podczas uruchamiania, to folder, do którego chcę mieć dostęp w wersjach DEV, INT i PROD aplikacji, bez zakodowania ścieżki na stałe.

Oto wizualizacja mojego przypadku użycia:

wprowadź opis obrazu tutaj

  • Foldery w niebieskich ramkach to moje lokalizacje katalogów dla aplikacji każdego środowiska.
  • Folder w czerwonym polu to katalog, do którego chcę uzyskać ścieżkę (co wymaga najpierw pobrania lokalizacji folderu wdrożonego aplikacji „MyClickOnceGreatApp_1_0_0_37”, która jest taka sama jak OP).

Nie znalazłem żadnych sugestii w tym pytaniu ani ich komentarzy do pracy przy zwracaniu folderu, w którym wdrożono aplikację Clickonce (do którego następnie przenosiłbym się względem tego folderu, aby znaleźć interesujący folder). Żadne inne wyszukiwanie w Internecie ani powiązane pytania SO również nie przyniosły odpowiedzi.

Wszystkie sugerowane właściwości albo kończyły się niepowodzeniem, ponieważ obiekt (np. ActivationUri) był pusty, albo wskazywały na folder zainstalowanej aplikacji w pamięci podręcznej lokalnego komputera. Tak, mogłem z wdziękiem obsługiwać obiekty zerowe, sprawdzając IsNetworkDeployed - to nie jest problem - ale, co zaskakujące, IsNetworkDeployed zwraca wartość false, mimo że w rzeczywistości mam lokalizację folderu wdrożonego w sieci dla aplikacji Clickonce. Dzieje się tak, ponieważ aplikacja jest uruchamiana z lokalnych, zbuforowanych bitów.

Rozwiązaniem jest przyjrzenie się:

  • AppDomain.CurrentDomain.BaseDirectory gdy aplikacja jest uruchamiana w Visual Studio w miarę rozwoju i
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation gdy wykonuje się normalnie.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationwe wszystkich przypadkach poprawnie zwraca katalog sieciowy, w którym moja aplikacja Clickonce jest wdrożona. To znaczy, gdy jest uruchamiany przez:

  • setup.exe
  • MyClickOnceGreatApp.application
  • Skrót na pulpicie tworzony przy pierwszej instalacji i uruchomieniu aplikacji.

Oto kod, którego używam podczas uruchamiania aplikacji, aby uzyskać ścieżkę do folderu WorkAccounts. Uzyskanie folderu wdrożonej aplikacji jest proste, ponieważ nie prowadzi się do katalogów nadrzędnych:

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
źródło
0

Zakładając, że pytanie dotyczy dostępu do plików w folderze aplikacji po zainstalowaniu aplikacji ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) na komputerze użytkownika, istnieją trzy sposoby uzyskania tego folderu przez samą aplikację:

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.

Działają one z VS IDE i z wdrożonej / zainstalowanej aplikacji ClickedOnce, nie jest wymagane sprawdzenie „true == System.Deployment.ApplicationDeploy.IsNetworkDeployed”. ClickOnce przejmuje wszystkie pliki zawarte w projekcie programu Visual Studio 2017, dzięki czemu aplikacja może uzyskać dostęp do wszystkich wdrożonych plików przy użyciu ścieżek względnych z poziomu aplikacji.

Jest to oparte na systemie Windows 10 i programie Visual Studio 2017

BoiseBaked
źródło