2015-06-24 2 views
0

Я написал автоматический процесс сборки, как приложение .NET 4 на C#. Я вызываю MSBuild.exe, используя System.Diagnostics.Process. Создаваемый проект написан в Delphi XE5. Затем я прочитал версию исполняемого файла, который был только построен:FileVersionInfo вывода из MSBuild

version = System.Diagnostics.FileVersionInfo.GetVersionInfo(fileName).FileVersion; 

(я не могу использовать Sytem.Reflection.Assembly класс, потому что это приложение Delphi).

Если я делаю это в приложении консоли, он отлично работает. Версия возвращается, например, "1.2.3.4". Но точно такой же код, как и для службы Windows, я получаю пустую строку, как будто у файла нет информации о версии. Те же самые учетные данные ОС в обоих случаях.

Возможно, информация о версии кэшируется с момента ее создания MSBuild? Но почему разница между консолью и сервисом? Любые идеи, как заставить перезагружать информацию о версии? Я пробовал FileInfo.Refresh - нет разницы.

(я знаю, что я мог бы использовать MSBuild программно, это только казалось проще назвать ехе, без необходимости осуществлять регистратор.)

Update: Я изменил его назвать MSBuild программно, через класс Microsoft.Build.Execution.BuildManager , а не MSBuild.exe. Не было никакой разницы.

+0

Хм, нет, класс FileVersionInfo довольно упрощен и не имеет сильной зависимости от среды выполнения. Более вероятным объяснением является то, что сборка не прошла хорошо, а исполняемый файл просто не имеет ресурса версии. Легко проверить с помощью Explorer. –

+0

Нет проблем с исполняемым файлом - он имеет правильную версию. –

ответ

0

Похоже, что это не связано с MSBuild. Я думаю, что это ошибка в методе CLR, в том, как он обрабатывает относительные пути.

Перед вызовом GetVersionInfo текущий каталог изменен. Путь к файлу относительный. Глядя на декомпилированный код для GetVersionInfo, он сначала проверяет файл существует:

if (!File.Exists(fileName)) 
{ 
    new FileIOPermission(FileIOPermissionAccess.Read, FileVersionInfo.GetFullPathWithAssert(fileName)).Demand(); 
    throw new FileNotFoundException(fileName); 
} 

Исключение не выкинули, так что немного доволен относительного пути.

Но к тому времени fileName получает через к методам API в Microsoft.Win32.UnsafeNativeMethods, он не признал:

int fileVersionInfoSize = Microsoft.Win32.UnsafeNativeMethods.GetFileVersionInfoSize(fileName, out handle); 

я преобразовал fileName на полный путь, прежде чем передать его в GetVersionInfo, и теперь он работает.

Смежные вопросы