读取注册表项失败,MSBuild扩展包4.0
我正在使用MSBuild扩展包4.0进行本地开发部署。使用类MSBuild.ExtensionPack.Computer.Registry读取注册表项(以获取安装目录)时,指出路径无效失败。我认为这是由于msbuild是一个32位进程,因此它只能看到:读取注册表项失败,MSBuild扩展包4.0,msbuild,registry,msbuild-4.0,Msbuild,Registry,Msbuild 4.0,我正在使用MSBuild扩展包4.0进行本地开发部署。使用类MSBuild.ExtensionPack.Computer.Registry读取注册表项(以获取安装目录)时,指出路径无效失败。我认为这是由于msbuild是一个32位进程,因此它只能看到: HKEY_LOCAL_MACHINE\Software\SysWow6432\* 而不是 HKEY_LOCAL_MACHINE\Software\* 有没有人找到了一种方法来解决这个问题,而不必重新开发自定义工具 我的实际剧本: <MS
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>
您是否已尝试使用MSBuilds内置支持读取注册表
<PropertyGroup>
<CrmPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM@CRM_Server_InstallDir</CrmPath>
</PropertyGroup>
及
编辑 即使您正在处理一个多目标环境,您也可以使用内置方法解决这个问题
<!-- 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>
$(注册表:HKEY\U LOCAL\U MACHINE\SOFTWARE\SysWow64\*)
$(注册表:HKEY\U LOCAL\U MACHINE\SOFTWARE\*)
MSBuild通常能够判断它所处理的环境,因此您可以满足各种可能的组合,并在所有类型的计算机上使用相同的脚本。我通过查看.NET 4.0的新功能解决了这个问题(如此处所建议的:) 现在,如果需要32位或64位值,我可以在查找中指定:
<GetWindowsRegistryValue Key="SOFTWARE\Microsoft\MSCRM" Value="CRM_Server_InstallDir" Hive="LocalMachine" View="Registry64">
<Output PropertyName="CrmPath" TaskParameter="Setting"/>
</GetWindowsRegistryValue>
以及自定义(快速和肮脏)任务:
namespace Utilities.CustomBuildTasks
{
使用制度;
使用Microsoft.Build.Framework;
使用Microsoft.Win32;
///
///定义用于检索注册表值的自定义任务。
///
公共类GetWindowsRegistryValue:ITask
{
///
///获取或设置与任务关联的生成引擎。
///
///
///与任务关联的生成引擎。
公共IBuildEngine构建引擎
{
得到;
设置
}
///
///获取或设置与任务关联的任何主机对象。
///
///
///与任务关联的主机对象。
公共ITaskHost主机对象
{
得到;
设置
}
///
///获取或设置密钥。
///
///注册表项。
[必需]
公共字符串密钥
{
得到;
设置
}
///
///获取或设置该值。
///
///价值。
[必需]
公共字符串值
{
得到;
设置
}
///
///获取或设置配置单元。
///
///注册表配置单元。
[必需]
公共字符串蜂箱
{
得到
{
返回此.hive.ToString();
}
设置
{
this.hive=(RegistryHive)Enum.Parse(typeof(RegistryHive),value);
}
}
///
///配置单元枚举值。
///
专用注册蜂箱;
///
///获取或设置视图。
///
///视图(64位/32位)。
[必需]
公共字符串视图
{
得到
{
返回此.view.ToString();
}
设置
{
this.view=(RegistryView)Enum.Parse(typeof(RegistryView),value);
}
}
///
///视图枚举值。
///
私有注册视图;
///
///获取或设置设置。
///
///背景。
[输出]
公共字符串设置
{
得到;
设置
}
///
///执行任务。
///
///
///如果任务成功执行,则为true;否则为false。
///
公共bool Execute()
{
尝试
{
var baseKey=RegistryKey.OpenBaseKey(this.hive,this.view);
var subKey=baseKey.OpenSubKey(this.Key);
if(子键==null)
{
返回false;
}
this.Setting=subKey.GetValue(this.Value.ToString();
返回true;
}
捕获(例外)
{
返回false;
}
}
}
}
如果您使用的是MSBuild 4.0,还可以使用内置属性函数GetRegistryValueFromView(记录在)。
此函数允许指定64位或32位视图(或两者)
您的电话如下所示:
<PropertyGroup>
<CrmPath>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM', 'CRM_Server_InstallDir', null, RegistryView.Registry64, RegistryView.Registry32))</CrmPath>
</PropertyGroup>
$([MSBuild]::GetRegistryValueFromView('HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\MSCRM','CRM\U Server\U InstallDir',null,RegistryView.Registry64,RegistryView.Registry32))
使用MSBuild扩展包4.0,您还可以创建、修改和删除注册表项和值。但如果你只打算阅读,你可以先看一下@Thierry answer
对于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>
<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>
对于x86注册表节点视图
<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>
<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>
有关更多信息,请参阅。谢谢。这让我走上了正确的道路,@Henrik:不客气。。。但是我认为你为这个创建一个自定义任务有点过分了。我完全同意,如果我控制了在开发人员机器上运行的msbuild版本,那么这是过度设计的。不幸的是,我还没有,所以这似乎是最快和最兼容的方式。谢谢Thierry,这个项目不再运行,但很高兴知道有内置的方式可以访问64位和32位版本的注册表。我还没有测试过这个问题,但是改变我接受的解决方案,因为这是一个更好的解决方法。
<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>