Удалить предыдущую версию файла настроек пользователя и каталог конфигурации после обновления 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);
}
}