Картинка блога

Во время написания своего диспетчера обновлений, наткнулся на одну задачку. Версия последнего обновления сравнивается с версией самого приложения и если последняя устарела, должна осуществятся замена файла с сервера. Оказалось, что проблема не тривиальна, за исключением тех, кто держит все классы и «неймспейсы» .NET в голове.

Для начала, простой пример с очевидным недостатком:

string pathToExecutable = Environment.CurrentDirectory;//Application.StartupPath.ToString();
string appExecutable = "AppTest.exe";
string fullAppExecutable = String.Format("{0}\\{1}", pathToExecutable, appExecutable);
var app = Assembly.LoadFile(fullAppExecutable); //Загружаем наш файл сборки.
var version = app.GetName().Version; //Получаем версию сборки

Естественно, после загрузки сборки, мы с ней как с файлом ничего сделать не сможем, так как она теперь будет использоваться до конца жизни программы.

Альтернативный вариант, загрузка сборки в отдельный домен приложения. AppDomain имеет метод Unload, который, теоретически должен сделать, то что надо.

AppDomain domain = AppDomain.CreateDomain("version getter");
var app = domain.Load("AppTest"); //загрузить сборку в наш домен.
var version = app.GetName().Version;
AppDomain.Unload(domain); //выгрузить домен из памяти

Но как ни странно, система не спешит отпускать файл к записи. Так что сразу получить доступ к нему не получится, возможно система это сделает позже, не проверял. Еще одной особенностью AppDomain является отсутствие метода LoadFile. По этому сборки можно загружать только по имени сборки, а значит она должна находится в текущей папке, системной папке или GAC.

Оказалось, что решение проще простого, просто искать его надо в System.Diagnostics

var vi = FileVersionInfo.GetVersionInfo(fullAppExecutable);
var version = new Version(vi.ProductVersion);

Вот он, FileVersionInfo просто читающий информацию, не локающий метод.

Метки:,

2 комментария в “Версия .NET сборки без блокирования файла.”

  1. Большое спасибо!…сам занимаюсь подобной задачей и как раз встрял при определении версий нескольких сборок с одним именем, помещенных в разные каталоги(методы Assembly не могут загрузить сразу несколько одноименных файлов сборок из разных каталогов в один домен приложения)

  2. Все конечно замечательно… но зачем такие танцы с бубном?
    var assemblyName = AssemblyName.GetAssemblyName(assemblyFileName);
    данный метод получает имя сборки без ее загрузки.