Як отримати шлях до папки для програми ClickOnce


160

Мені потрібно записати файл у ту саму папку, де консоль ClickOnce .application (виконуваний файл). Папка, з якої вона запускається.

Я спробував використовувати Application.StartupPath&, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) але шлях вказує на підпапку під c:\Documents & Settings. Як мені отримати шлях, де .applicationпроживає?

Відповіді:


253

Щоб знайти місце розташування папки, ви можете просто запустити додаток, відкрити диспетчер завдань (CTRL-SHIFT-ESC), вибрати додаток і клацнути правою кнопкою миші | Відкрити розташування файлу.


3
ей, про пораду! але він не доступний на старих хитріх машинах XP. :)
Джалал

5
@Jalal для "старих шалених машин", перейдіть на веб-сайт www.SysInternals.com та завантажте Explorer Explorer. Я підозрюю, що зміни в TaskManager Win7, а потім Win8 були просто скопійовані з нього.
Аріох '21

1
Як цього домогтися, коли ваша програма працює на комп'ютері замовника?
користувач3285954

2
Що робити, якщо я не можу запустити програму, оскільки вона видалить файл журналу, який мені відчайдушно потрібен?
Томаш Зато - Відновити Моніку

2
@Tony_Henrich ви повинні відзначити це правильною відповіддю
sparkyShorts

120

шлях вказує на підпапку під c: \ Documents & Settings

Це вірно. ClickOnce applicationsвстановлюються під профілем користувача, який їх встановив. Ви взяли шлях, який дав вам отримання інформації з виконавчої збірки, і пішли перевірити це?

У Windows Vista та Windows 7 кеш ClickOnce ви знайдете тут:

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

У Windows XP ви знайдете його тут:

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

1
Я все це розумію. Я хочу папку, звідки я натиснув додаток. У мене немає доступу до C: \ Документів та налаштувань, тому я не матиму доступу до файлу журналу, якщо я буду використовувати шлях до папки, повернутий цією функцією, і я не хочу використовувати жорстко кодовані значення шляху .
Tony_Henrich

25

ApplicationDeployment.CurrentDeployment.ActivationUri може працювати

"Рядок нульової довжини, якщо властивість TrustUrlParameters в маніфесті розгортання помилкове або якщо користувач надав UNC для відкриття розгортання або відкрив його локально. В іншому випадку значенням повернення є повна URL-адреса, яка використовується для запуску програми, включаючи будь-які параметри. "


Але я думаю, що ви дійсно хочете, це ApplicationDeployment.CurrentDeployment.DataDirectory, який дає вам папку, в яку можна записувати дані. Після оновлення програми ви втратите те, що було в оригінальній папці .exe, але ви можете перемістити каталог даних до нової версії програми. Ваш додаток може записувати в цю папку будь-які файли журналу, - і я впевнений, що його можна буде записати.


Я нічого не робив, але файли зі старого DataDirectory автоматично копіюються в новий DataDirectory після розгортання. Також немає .pre довідників. (.NET Framework 3.5 та 4.5)
Der_Meister

15

Я використовую, Assembly.GetExecutingAssembly().Locationщоб отримати шлях до ClickOnceрозгорнутої програми в .Net 4.5.1.

Однак ви не повинні писати в будь-яку папку, де ваша програма буде розміщена ніколи, незалежно від способу розгортання (xcopy, ClickOnce, InstallShield тощо), оскільки вони зазвичай читаються лише для програм, особливо в новіших версіях Windows та серверах.

Додаток завжди повинен записувати в папки, зарезервовані для таких цілей. Ви можете отримати папки, які вам потрібні, починаючи з Environment.SpecialFolder Enumeration. На сторінці MSDN пояснюється, для чого призначена кожна папка: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Тобто для даних, журналів та інших файлів, які можна використовувати ApplicationData(роумінг), LocalApplicationData(локальний) або CommonApplicationData. Для тимчасових файлів використовуйте Path.GetTempPathабо Path.GetTempFileName.

Вищезазначене також працює на серверах та настільних комп’ютерах.

EDIT: Assembly.GetExecutingAssembly()викликається в основному виконуваному файлі.


Це працює для мене для програми ClickOnce, а також для роботи в середовищі VS Dev під час налагодження цього самого додатка.
Developer63

3

Програми ClickOnce DO перебувають у підкаталозі C: ​​\ Documents & Settings. У них немає "чистих" каталогів встановлення, оскільки локальні файли, по суті, "тимчасово" завантажуються, щоб програма могла працювати на локальному ПК, а виконання програми контролюється з сервера ClickOnce, на який вони розгорнуті залежно від налаштувань публікації. (Перевірка на оновлення, вимоги до версії тощо).


У мене немає доступу до папки C: \ Documents & Settings на сервері, що означає, що я не маю доступу до файлу, який створює додаток. Я запускаю додаток із певної папки. Це папка, в якій публікується додаток. Як отримати шлях до цієї папки?
Tony_Henrich

О, ви хочете URL-адресу розгортання. Вибачте, я цього зовсім не зрозумів. Ви намагаєтеся отримати його з додатку ClickOnce або із зовнішнього додатка?
RobinDotNet

1

Ось що я виявив, що працював над тим, щоб отримати можливість розгорнутого місця розташування папки мого додатка для натискання, і це не було зазначено ніде, що я бачив у своїх пошуках, для мого аналогічного конкретного сценарію:

  • Додаток clickkonce розгорнуто у мережевій папці локальної мережі компанії.
  • Додаток "Clickkonce" встановлено таким чином, щоб він був доступний в Інтернеті чи офлайн.
  • У моїй установочній URL-адресі за допомогою кліку та в URL-адресах оновлення у властивостях мого проекту нічого не вказано. Тобто немає окремого місця для встановлення чи оновлення.
  • У своїх варіантах публікації у мене є ярлик на робочому столі, створений для програми clickkonce.
  • Папка, до якої я хочу отримати шлях при запуску, - це та, до якої я хочу отримати доступ до версій програми DEV, INT та PROD без жорсткого кодування шляху.

Ось наочний випадок мого використання:

введіть тут опис зображення

  • Папки із синім кольором - це мій каталог каталогів для кожної програми.
  • Папка з червоною коробкою - це каталог, до якого я хочу пройти шлях (для якого потрібно спочатку отримати місце розгорнутої програми в папці "MyClickOnceGreatApp_1_0_0_37", що таке саме, як і ОП).

Я не знайшов жодної із пропозицій у цьому запитанні чи їх коментарів, які б спрацювали над поверненням папки, в яку було розгорнуто додаток clickkonce (що я потім переміщу відносно цієї папки, щоб знайти цікаву папку). Жоден інший пошук в Інтернеті або пов'язані з цим питання запитання також не знайшли відповіді.

Усі запропоновані властивості або були відмовлені через те, що об’єкт (наприклад, ActivationUri) є недійсним, або вказували на кешовану папку встановленого додатка місцевого ПК. Так, я міг вишукано обробити нульові об’єкти, перевіривши IsNetworkDeployed - це не проблема - але дивно, IsNetworkDeployed повертає помилкові дані, хоча у мене фактично є розгорнуте мережеве розташування папок для програми clickkonce. Це тому, що програма працює з локальних, кешованих бітів.

Рішення полягає в тому, щоб переглянути:

  • AppDomain.CurrentDomain.BaseDirectory коли програма запускається у візуальній студії в міру розвитку і
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation коли воно виконується нормально.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationправильно повертає мережевий каталог, в який розгорнуто мою програму clickkonce, у всіх випадках. Тобто, коли він запускається через:

  • setup.exe
  • MyClickOnceGreatApp.application
  • Ярлик на робочому столі, створений після першого встановлення та запуску програми.

Ось код, який я використовую при запуску програми, щоб отримати шлях до папки WorkAccounts. Отримати розгорнуту папку додатків просто, просто не рухаючись до батьківських каталогів:

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

Якщо припустити питання щодо доступу до файлів у папці додатків після встановлення програми ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) на ПК користувача, це три способи отримати цю папку самим додатком:

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.

Вони працюють з VS IDE та з розгорнутого / встановленого додатку ClickedOnce, не потрібно перевіряти "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed". ClickOnce збирає будь-які файли, включені до проекту Visual Studio 2017, тому програма дійсно може отримати доступ до будь-яких та всіх розгорнутих файлів, використовуючи відносні шляхи в межах програми.

Це засновано на Windows 10 та Visual Studio 2017

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.