Я начал работать напрямую с MSBuild API, чтобы расширить наш процесс сборки и повысить гибкость.

Я успешно автоматизировал весь процесс создания нашего проекта, но не без нескольких "подводных камней". Из-за крайней нехватки документации и примеров использования API MSBuild мне пришлось выдержать несколько длительных сеансов отладки.

Надеюсь, описанные здесь детали помогут другим, желающим напрямую интегрироваться с MSBuild API.

Компилировать код C # было чрезвычайно просто, но как только я попытался использовать API MSBuild для компиляции некоторых из наших устаревших проектов VC ++, процесс действительно натолкнулся на препятствие.

Вот пример кода моей оболочки компилятора:

            globalProperties["Configuration"] = CommonLibrary.BuildMode.Release.ToString();

            //add the compiler variables from the specific project to the properties dictionary
            if (compilerVariables != null)
            {
                foreach(var kvp in compilerVariables)
                {
                    globalProperties.Add(kvp.Key, kvp.Value);
                }
            }

            //set up a build request to be sent to MSBuild
            var request = new BuildRequestData(project.SolutionFile.FullName, globalProperties, null, new string[] { "Rebuild" }, null);

            //configure settings for MSBuild specifically
            var buildParams = new BuildParameters();
            buildParams.EnableNodeReuse = true;

            buildParams.Loggers = new List<Microsoft.Build.Framework.ILogger>() 
            {
                buildLogger,
                fileLogger
            };

            //instantiate the BuildManager, kick off the build, and get the results
            BuildManager buildManager = new BuildManager();
            project.BuildResult = buildManager.Build(buildParams, request);

Другой аспект этого процесса включает файл .props, который VC ++ использует для получения INCLUDE (и других путей), необходимых для компоновщика. Этот файл .props находится в C: \ Users \% BUILDACCOUNT% \ AppData \ Local \ Microsoft \ MSBuild \ v4.0 \ Microsoft.Cpp.% TargetPlatform% .user.props

Теперь начинается интересная часть.

Когда я запускаю этот код для проекта / решения C #, все работает нормально. Это связано с тем, что файл .props не играет никакой роли в компиляции C # (пути включения сохраняются как уровень .csproj).

Однако при работе с решением, содержащим проекты VC ++, этот метод совершенно неуместен. Причина в том, что он не может разрешить пути INCLUDE, которые предположительно находятся в файле props (в месте, указанном выше).

Еще один интересный момент заключается в том, что я могу реплицировать аргументы в MSBuild прямо из командной строки, и сборка завершается успешно. Это меня очень озадачило ... поэтому я включил подробную диагностику и снова запустил свой тестовый пример.

Интересная информация из логов (логи обрезаны):

  1. Сборка из командной строки

USERDOMAIN = [УДАЛЕНО]

USERNAME = MyUserName

LOCALAPPDATA = C: \ Users \ MyUserName \ AppData \ Local

  1. Сборка из API

USERDOMAIN = [УДАЛЕНО]

ИМЯ ПОЛЬЗОВАТЕЛЯ = BUILDMACHINE $

LOCALAPPDATA = C: \ Windows \ system32 \ config \ systemprofile \ AppData \ Local

Как видите, похоже, что текущий идентификатор при сборке из интерфейса командной строки правильно настроен на мою личность. Однако сборка из API устанавливает текущую идентификацию в локальной системе. Это приводит к неправильной установке пути INCLUDE для сборок API, поскольку файл свойств с этой информацией недоступен в ожидаемом месте (C: \ Windows \ system32 \ config \ systemprofile \ AppData \ Local).

Мой обходной путь, который, кажется, работает до сих пор, - это фактически переместить все файлы props из местоположения AppData в каталог, в котором API ожидает его. Я не думаю, что это ожидаемое поведение ... это не похоже очень внятно.

Дополнительные примечания:

  • Этот код размещается в IIS в пуле приложений, работающем как «MyUserName» (а не в локальной системе).
  • Мне удалось воспроизвести эту проблему на двух разных машинах, работающих под управлением Windows Server 2008.

Либо я что-то делаю неправильно, либо API MSBuild что-то делает неправильно? Любой ввод относительно официальных средств получения файла реквизита, распознанного API MSBuild, был бы чрезвычайно полезен.

Спасибо.

0
Localghost 29 Апр 2013 в 17:34

1 ответ

Лучший ответ

Хорошо, я понял, в чем проблема.

Проблема не связана с MSBuild. Вместо этого это связано с моей конфигурацией IIS.

Хотя мой пул приложений работал под идентификатором моей учетной записи сборки, у меня была опция «Загрузить профиль пользователя = False», из-за которой в профиле пользователя по умолчанию использовалась LocalSystem.

Переключение этого параметра на «Загрузить профиль пользователя = True» устранило эту проблему, и MSBuild начал получать доступ к правильному файлу .props.

1
Localghost 29 Апр 2013 в 20:31