В свойствах проекта Visual Studio для приложения есть опция «Создать приложение без манифеста». Эта опция необходима при развертывании приложения через ClickOnce, но я не понимал, что делает эта опция , и мои исследования пока заключаются в следующем ...

При отключении этой опции и повторной компиляции я заметил, что манифест сборки .NET, в котором перечислено содержимое сборки, остался нетронутым и не изменился. При сравнении двоичных файлов (с использованием режима сравнения Hex в Beyond Compare) я заметил, что этот фрагмент был удален с конца образ EXE:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Я считаю, что это манифест исполняемого приложения Windows, как описано в MSDN (Application Манифесты):

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

Странно то, что имя и версия приложения в приведенном выше XML-коде имеют значения по умолчанию (MyApp, версия 1.0.0.0), тогда как проект Visual Studio, который создает этот двоичный файл, имеет собственное имя и номер версии, поэтому он < em> Мне кажется , что все двоичные файлы .NET (или EXE-файлы в любом случае) имеют тот же встроенный манифест WindowsEXE по умолчанию. Так ли это? И следует ли мне где-то устанавливать эти значения имени и версии?

2
redcalx 30 Май 2013 в 14:53

1 ответ

Лучший ответ

Имя, представленное в манифесте, является логическим именем. Нет необходимости, чтобы он действительно совпадал с именем EXE. Он используется Windows только в одном сценарии, который упоминается в описании, в случае «частных параллельных сборок».

Параллельные сборки важны в неуправляемых приложениях, использующих библиотеки DLL. Это решает проблему DLL Hell, такие приложения извлекают DLL не только по имени, но и по версии. Вы найдете место, где эти «сборки» хранятся на вашем компьютере в c: \ windows \ winsxs. Очень немногие коммерческие программы действительно используют эту функцию, это довольно большая головная боль, и документация очень бедна, вы почти всегда найдете библиотеки DLL Microsoft в этом каталоге. Он немного увеличился со времен Vista, там же хранятся библиотеки DLL операционной системы.

Все это может показаться вам знакомым, в .NET тоже есть такой параллельный каталог. Не хранится в одном месте и не под тем же именем. Мы называем это GAC, Global Assembly Cache. В остальном внутренняя сеть такая же, но намного проще использовать, поскольку поддержка Fusion api встроена непосредственно в CLR. И не требует манифеста, сборки .NET уже имеют необходимые атрибуты в их метаданных сборки. Однако манифест по-прежнему требуется в исполняемом файле .NET для других вещей, которые выполняет манифест. Тот, который вы опубликовали, важен, он сообщает Windows, что ваша программа поддерживает UAC и не требует лжи, когда она делает такие вещи, как запись ключей реестра в HKLM или копирование файлов в c: \ windows. Имя и версия приложения указаны, потому что они не являются обязательными.

Короче говоря, ни имя, ни версия в манифесте на самом деле не имеют значения для программ .NET.

7
Hans Passant 30 Май 2013 в 19:19