Удалить предыдущую версию файла настроек пользователя и каталог конфигурации после обновления C#

У меня есть приложение C#, которое хранит пользовательские настройки в стандартном файле user.config.

Это, очевидно, находится в каталоге с именем номера версии приложения, т.е.

My_App / 1.0.0.0 / user.config

После успешного обновления до новой версии моего приложения (1.0.0.1) настройки из v1.0.0.0 копируются и сохраняются в новой версии 1.0.0.1. Это легкая часть.

Теперь я хочу удалить эту предыдущую версию каталога 1.0.0.0 после обновления.

Я понимаю, что путь к каталогу не может быть жестко запрограммирован, так как местоположение зависит от среды.

Я искал использовать:

using System.Configuration;
...
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
        MessageBox.Show("Local user config path: {0}", config.FilePath);

сразу выдает ошибку и мне нужно добавить:

using EnvDTE;

теперь у меня есть ошибки:

CS0117 "ConfigurationManager" не содержит определения для "OpenExeConfiguration"

CS0103 Имя "ConfigurationUserLevel" не существует в текущем контексте

CS1061 "Конфигурация" не содержит определения для "FilePath", и невозможно найти метод расширения "FilePath", принимающий первый аргумент типа "Конфигурация" (вам не хватает директивы using или ссылки на сборку?)

Это можно обойти?

В противном случае при каждом обновлении будет создаваться новый каталог, и, хотя каждый из них занимает всего 1 КБ, кажется нелепым позволять всем им монтироваться.

Кроме того, мое приложение не установлено в системе пользователей, оно все запускается непосредственно из распространяемого.exe


ОБНОВЛЕНИЕ 1


Добавление ошибок с использованием EnvDTE; УДАЛЕНО согласно комментарию.

CS0246 Не удалось найти тип или имя пространства имен "Конфигурация" (отсутствует директива using или ссылка на сборку?)

CS0103 Имя "ConfigurationManager" не существует в текущем контексте

CS0103 Имя "ConfigurationUserLevel" не существует в текущем контексте


ОБНОВЛЕНИЕ 2


Я думал, что получаю где-то с помощью:

string path = Application.LocalUserAppDataPath;
        MessageBox.Show(path);

вместо этого, но это просто создает новый путь вдоль стороны моего оригинала с пустым <Program Version> справочник в виде:

<Company Name>/<Program Name>/<Program Version>

В актуальном user.config путь <Program Name> к нему добавлена ​​хеш-строка для создания чего-то похожего на:

<Program Name.exe_Url_aqod5o1hapcyjk3ku1gpyynhem0mefle>

Я бы предположил, что этот хэш не является константой и зависит от машин и установок


ОБНОВЛЕНИЕ 3


Наконец я смог получить точный путь к user,config файл как это:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
       MessageBox.Show(config.FilePath);

using System.Configuration не работал, и я не понял, что это было отображено в коде в несколько более тусклом цвете, потому что на него не было ссылок, поэтому я добавил его в качестве ссылки, щелкнув правой кнопкой мыши решение в проводнике.

Сейчас config содержит полный путь к user.config файл, как в моем случае под управлением Windows 10:

<DRIVE LETTER>\Users\<USER NAME>\AppData\Local\<Company Name>\<Program Name>\<Program Version>\user.config

Мне нужно манипулировать config струна и вылезти из <Program Version> каталог & до <Program Name> каталог, чтобы проверить, есть ли какие-либо каталоги под ним, кроме текущего <Program Version> каталог и, если есть, мне нужно удалить их.


ОБНОВЛЕНИЕ 4


Хорошо, действительно где-то сейчас. Я манипулировал строкой filePath для того, чтобы быть на уровне <Program Version> родитель и используя этот код:

string FullfilePath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
        string ProgNamefilePath = Path.GetFullPath(Path.Combine(FullfilePath, @"..\..\"));
        Directory.Delete(ProgNamefilePath, true);
        //MessageBox.Show(ProgNamefilePath);//For Testing Purposes

Я могу удалить все каталоги под этим, отлично.

Нет, я застрял, так как не хочу удалять все каталоги, относящиеся к <Program Version> но только тот, который не соответствует текущей версии.

Application.ProductVersion;

1 ответ

Решение

Бессонная ночь, думая об этом и пытаясь обдумать другие пути, я наконец-то придумал это, и это работает.

Есть, вероятно, более аккуратные способы сделать это, но в любом случае....

Так высоко в коде, что я мог бы разместить его, чтобы, надеюсь, сделать его чрезвычайно очевидным для себя при кодировании обновлений, я разместил это:

public class MainForm : Form
  {
//***********************************
//***********************************
//**** THIS RELEASE IS v1.0.0.1 ****
//***********************************
//****** REMEMBER TO EDIT THIS ******
//***********************************
const string DeleteThisVersionDirectory = "1.0.0.0"; //**** Set this to the <Program Version> Directory to be Deleted on Upgrade, usually version prior to new release. ****
//***********************************
//***********************************

Вы можете видеть, что он находится прямо под Form открытие для видимости.

Затем я создал этот метод:

private void ApplicationUpdate()
    {
        string FullfilePath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
        string VersionDirectoryfilePath = Path.GetFullPath(Path.Combine(FullfilePath, @"..\..\" + DeleteThisVersionDirectory));
        if (Properties.Settings.Default.UpdateSettings)
        {
            Properties.Settings.Default.Upgrade();
            Properties.Settings.Default.UpdateSettings = false;
            Properties.Settings.Default.Save();
            Directory.Delete(VersionDirectoryfilePath, true);
        }
    }

этот метод называется здесь:

public MainForm()
    {
        InitializeComponent();
        ApplicationUpdate();
        GetSettingsValues();
    }

Все работает отлично, поэтому после удачного Upgrade где пользовательские настройки передаются в user.config НОВОЙ версии программы, каталог предыдущей версии программы и user.config файл удален

Я просто должен помнить, чтобы изменить const string DeleteThisVersionDirectory на каждой версии обновлять кодировку.

Вот как я это сделал. После обновления я удаляю все папки user.config, кроме самой папки. Поэтому мне не нужно вручную добавлять текущую версию вверху. Надеюсь, это поможет. Я знаю, что пост немного старше, но может кому-то помочь. В моем приложении я делаю это в трех частях, чтобы все работало хорошо.

а) глобальная переменная в пользовательском интерфейсе

bool DeleteOldDirectories = false;

б) В моем Main() перед пользовательским интерфейсом я обновляю свойства и сохраняю их в моей новой версии.

if (Settings.Default.UpgradeRequired)
            {
                Settings.Default.Upgrade();
                Settings.Default.UpgradeRequired = false;
                Settings.Default.Save();
                DeleteOldDirectories = true;
            }

В методе Window.Loaded после того, как мой пользовательский интерфейс загружен и я уверен, что все свойства обновлены правильно, я удаляю старые каталоги, поэтому все изменения с этого момента сохраняются в моей последней версии, и все ссылки на старые версии исчезли.

 if (deleteOldDirectories)
        {
            string FullfilePath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
            string VersionDirectoryfilePath = System.IO.Path.GetFullPath(System.IO.Path.Combine(FullfilePath, @"..\..\"));
            string[] fileEntries = Directory.GetDirectories(VersionDirectoryfilePath);
            foreach (string filename in fileEntries)
            {
             //   MessageBox.Show(filename);
                if (filename != VersionDirectoryfilePath + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString())
                    Directory.Delete(filename, true);
            }
        }
Другие вопросы по тегам