2010-07-01 4 views
2

J'utilise MSBuild Extension Pack 4.0 pour effectuer mon déploiement de développement local. Lors de l'utilisation de la classe MSBuild.ExtensionPack.Computer.Registry pour lire une clé de registre (pour obtenir un répertoire d'installation), elle échoue et indique que le chemin n'est pas valide. Je crois que cela est dû à msbuild être un processus 32 bits, donc il ne peut voir:La lecture de la clé de registre échoue avec MSBuild Extension Pack 4.0

HKEY_LOCAL_MACHINE\Software\SysWow6432\* 

et non

HKEY_LOCAL_MACHINE\Software\* 

Quelqu'un at-il trouvé un moyen de contourner cela sans revenir à l'élaboration d'un outil personnalisé ?

Mon script actuel:

<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> 

Répondre

2

Si vous utilisez MSBuild 4.0, vous pouvez ainsi iuse la fonction de propriété intégrée GetRegistryValueFromView (Documente d au https://msdn.microsoft.com/en-us/library/dd633440.aspx#BKMK_GetRegistryValueFromView). Cette fonction permet de spécifier les 64 bits ou vue 32 bits (ou les deux)

Votre appel ressemblerait à ceci:

<PropertyGroup> 
    <CrmPath>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM', 'CRM_Server_InstallDir', null, RegistryView.Registry64, RegistryView.Registry32))</CrmPath> 
</PropertyGroup> 
+0

Merci Thierry, ce projet ne fonctionne plus, mais il est bon de savoir qu'il existe des moyens d'accéder aux versions 64 et 32 ​​bits du registre. Je n'ai pas testé cela, mais en changeant ma solution acceptée car c'est une bien meilleure façon de le résoudre. – Henrik

2

vous déjà essayé Avez-MSBuilds soutien à la lecture builtin le registre?

<PropertyGroup> 
    <CrmPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\[email protected]_Server_InstallDir</CrmPath> 
</PropertyGroup> 

J'ai appris cela moi-même à partir de this blog posting.

En outre, vous pouvez exécuter MSBuild dans x86 et x64:

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

et

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

Modifier

Même si vous avez affaire à un environnement multicible vous pouvez résoudre cela avec des moyens intégrés.

<!-- 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 est généralement en mesure de dire quel environnement qu'il traite afin que vous puissiez répondre à toutes les combinaisons possibles et utiliser le même script sur toutes sortes de machines.

+0

Merci. Cela m'a mis sur le bon chemin avec http://stackoverflow.com/questions/2197086/create-64-bit-registry-key-non-wow64-from-a-32-bit-application – Henrik

+0

@Henrik: Vous ' re bienvenue ... mais je pense que vous en faites un peu trop avec la création d'une tâche personnalisée pour cela. – Filburt

+0

Je suis tout à fait d'accord avec le fait que ceci est sur-conçu si j'avais le contrôle sur la version de msbuild qui fonctionne sur les machines de développement. Malheureusement, je ne le fais pas (encore), donc cela semblait le moyen le plus rapide et le plus compatible. – Henrik

0

Je résolu ce problème en regardant les nouvelles fonctionnalités de .NET 4.0 (comme le suggère ici: Create 64 bit registry key (non-WOW64) from a 32 bit application)

Je peux maintenant préciser dans la recherche si je besoin d'une valeur 32 bits ou 64 bits:

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

et la tâche sur mesure (rapide et sale):

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; 
      } 
     } 
    } 
} 
0

Avec MSBuild Extension Pack 4.0, vous pouvez également créer, modifier et supprimer registre clés et valeurs. Mais si vous avez seulement l'intention de lire, jetez un coup d'œil à la réponse @Thierry.

Pour le noeud Registre x64 vue

<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> 

Pour vue nœud de Registre 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> 

Pour plus d'informations, voir RegistryView on MSDN.

Questions connexes