Сбой чтения раздела реестра с пакетом расширений MSBuild 4.0 - PullRequest
2 голосов
/ 01 июля 2010

Я использую MSBuild Extension Pack 4.0 для локального развертывания. При использовании класса MSBuild.ExtensionPack.Computer.Registry для чтения раздела реестра (для получения каталога установки) происходит сбой, говоря, что путь неверен. Я полагаю, что это связано с тем, что msbuild является 32-разрядным процессом, поэтому он может видеть только:

HKEY_LOCAL_MACHINE\Software\SysWow6432\*

а не

HKEY_LOCAL_MACHINE\Software\*

Кто-нибудь нашел способ обойти это, не возвращаясь к разработке специального инструмента?

Мой настоящий сценарий:

<MSBuild.ExtensionPack.Computer.Registry TaskAction="Get" RegistryHive="LocalMachine" Key="SOFTWARE\Microsoft\MSCRM" Value="CRM_Server_InstallDir">
  <Output PropertyName="CrmPath" TaskParameter="Data"/>
</MSBuild.ExtensionPack.Computer.Registry>

Ответы [ 4 ]

2 голосов
/ 04 февраля 2015

Если вы используете MSBuild 4.0, вы также можете использовать встроенную функцию свойств GetRegistryValueFromView (задокументировано на https://msdn.microsoft.com/en-us/library/dd633440.aspx#BKMK_GetRegistryValueFromView). Эта функция позволяет указать 64-битное или 32-битное представление (или оба)

Ваш звонок будет выглядеть так:

<PropertyGroup>
    <CrmPath>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM', 'CRM_Server_InstallDir', null, RegistryView.Registry64, RegistryView.Registry32))</CrmPath>
</PropertyGroup>
2 голосов
/ 01 июля 2010

Вы уже пробовали встроенную поддержку MSBuilds для чтения реестра?

<PropertyGroup>
    <CrmPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM@CRM_Server_InstallDir</CrmPath>
</PropertyGroup>

Изучил это сам из этого блога .

Кроме того, вы можете запустить MSBuild вx86 и x64:

%WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe

и

%WINDIR%\Microsoft.NET\Framework64\v3.5\MSBuild.exe

Редактировать

Даже если вы работаете в многоцелевой средеВы можете решить эту проблему с помощью встроенных средств.

<!-- MSBuild 3.5 x86 / AnyCPU -->
<PropertyGroup Condition=" '$(MSBuildToolsPath)' == '$(windir)\Microsoft.NET\Framework\v3.5' AND '$(Platform)' == 'AnyCPU' ">
    <CrmPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\SysWow64\*)</CrmPath>
</PropertyGroup>

<!-- MSBuild 3.5 x64 -->
<PropertyGroup Condition=" '$(MSBuildToolsPath)' == '$(windir)\Microsoft.NET\Framework64\v3.5' AND '$(PLatform)' == 'x64' ">
    <CrmPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\*)</CrmPath>
</PropertyGroup>

MSBuild обычно может определить, с какой средой он имеет дело, поэтому вы можете обрабатывать все возможные комбинации и использовать один и тот же сценарий на всех типах машин.

0 голосов
/ 30 октября 2015

С MSBuild Extension Pack 4.0 вы также можете создавать, изменять и удалять ключи и значения реестра.Но если вы только планируете читать, вы можете сначала взглянуть на ответ @Thierry.

Для представления узла реестра x64

<MSBuild.ExtensionPack.Computer.Registry TaskAction="Get" RegistryView="Registry64" RegistryHive="LocalMachine" Key="SOFTWARE\Microsoft\MSCRM" Value="CRM_Server_InstallDir">
    <Output PropertyName="CrmPath" TaskParameter="Data"/>
</MSBuild.ExtensionPack.Computer.Registry>

Для представления узла реестра x86

<MSBuild.ExtensionPack.Computer.Registry TaskAction="Get" RegistryView="Registry32" RegistryHive="LocalMachine" Key="SOFTWARE\Microsoft\MSCRM" Value="CRM_Server_InstallDir">
    <Output PropertyName="CrmPath" TaskParameter="Data"/>
</MSBuild.ExtensionPack.Computer.Registry>

Для получения дополнительной информации см. RegistryView на MSDN .

.
0 голосов
/ 02 июля 2010

Я решил эту проблему, взглянув на новые возможности .NET 4.0 (как предлагается здесь: Создание 64-битного ключа реестра (не WOW64) из 32-битного приложения )

Теперь я могу указать в поиске, нужно ли мне 32-битное или 64-битное значение:

<GetWindowsRegistryValue Key="SOFTWARE\Microsoft\MSCRM" Value="CRM_Server_InstallDir" Hive="LocalMachine" View="Registry64">
  <Output PropertyName="CrmPath" TaskParameter="Setting"/>
</GetWindowsRegistryValue>

И пользовательская (быстрая и грязная) задача:

namespace Utilities.CustomBuildTasks
{
    using System;
    using Microsoft.Build.Framework;
    using Microsoft.Win32;

    /// <summary>
    /// Defines the custom task to retrieve registry values.
    /// </summary>
    public class GetWindowsRegistryValue : ITask
    {
        /// <summary>
        /// Gets or sets the build engine associated with the task.
        /// </summary>
        /// <value></value>
        /// <returns>The build engine associated with the task.</returns>
        public IBuildEngine BuildEngine
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets any host object that is associated with the task.
        /// </summary>
        /// <value></value>
        /// <returns>The host object associated with the task.</returns>
        public ITaskHost HostObject
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the key.
        /// </summary>
        /// <value>The registry key.</value>
        [Required]
        public string Key
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        [Required]
        public string Value
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the hive.
        /// </summary>
        /// <value>The registry hive.</value>
        [Required]
        public string Hive
        {
            get
            {
                return this.hive.ToString();
            }

            set
            {
                this.hive = (RegistryHive)Enum.Parse(typeof(RegistryHive), value);
            }
        }

        /// <summary>
        /// The hive enumeration value.
        /// </summary>
        private RegistryHive hive;

        /// <summary>
        /// Gets or sets the view.
        /// </summary>
        /// <value>The view (64-bit/32-bit).</value>
        [Required]
        public string View
        {
            get
            {
                return this.view.ToString();
            }

            set
            {
                this.view = (RegistryView)Enum.Parse(typeof(RegistryView), value);
            }
        }

        /// <summary>
        /// The view enumeration value.
        /// </summary>
        private RegistryView view;

        /// <summary>
        /// Gets or sets the setting.
        /// </summary>
        /// <value>The setting.</value>
        [Output]
        public string Setting
        {
            get;
            set;
        }

        /// <summary>
        /// Executes a task.
        /// </summary>
        /// <returns>
        /// true if the task executed successfully; otherwise, false.
        /// </returns>
        public bool Execute()
        {
            try
            {
                var baseKey = RegistryKey.OpenBaseKey(this.hive, this.view);

                var subKey = baseKey.OpenSubKey(this.Key);

                if (subKey == null)
                {
                    return false;
                }

                this.Setting = subKey.GetValue(this.Value).ToString();

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
...