问题描述
|
我已经将开发移植到另一台计算机,并且如果我运行项目,则有以下例外情况:
无法获取StrongNameKeyPair的公钥。
HibernateException:创建代理实例失败
在原始计算机上,它可以正常运行而不会出现问题。
我在Google上发现某些加密存在问题,因此我应该尝试\“ sn -m n \”,因为我不知道该怎么做。 sn.exe在更多文件夹中,我尝试从命令行运行,但它写道:
无法打开注册表项-无法格式化错误消息00000005
我不知道问题是否出在NHibernate上,还有更多类似的鞭打对话框,并且它仅在一种情况下抛出此异常。
有一部分代码异常抛出异常:
public IList<DTO> GetAll(GridSortOptions sortOptions,DTOListModel<DTO> listModel)
{
return GetAllCriteria(sortOptions,CreateCriteria(),listModel).List<DTO>();
}
解决方案中没有一个项目使用签名。
我不明白此错误的确切含义以及我应该寻找的内容。
解决方法
NHibernate正在动态创建.NET程序集(动态代理)并需要对其进行签名。默认情况下,Windows操作系统将加密密钥存储配置为计算机级别,并将密钥存储在C:\\ Documents and Settings \\ All Users \\ Application Data \\ Microsoft \\ Crypto \\ RSA \\ MachineKeys中。用户很可能可以在此文件夹中创建(例如)文本文件,但不能删除它,因为您没有完全控制权。
您的选择是
通过修改可能不建议使用的权限来完全控制C:\\ Documents and Settings \\ All Users \\ Application Data \\ Microsoft \\ Crypto \\ RSA \\ MachineKeys。
通过从Windows SDK运行\“ sn.exe -m n \”,将加密密钥存储更改为用户级别。 http://msdn.microsoft.com/zh-cn/library/k5b5tt23(v=VS.90).aspx这会将加密密钥存储区放在您的用户本地配置文件下,您应该始终对此进行完全控制。
在线上有几篇文章描述了类似的问题。例如,请参阅http://support.targetprocess.com/Default.aspx?g=posts&t=305。
,今天出现了类似的问题,但使用案例不同(在W2008R2机器上运行的.NET服务),但错误完全相同。
我使用procmon追溯到C:/ ProgramData / Microsoft / Crypto / RSA / MachineKeys中的密钥写入失败。
按照此处所述在文件夹上添加具有特殊权限的每个人的指导,可以解决此问题:http://toastergremlin.com/?p=432
另外,请确保您添加了所有人@本地计算机,而不是所有人@您的域!
,对于遇到此问题的其他人,我在物理机上也有相同的例外。一夜之间什么都没有改变,但是这种例外从早晨开始出现。
原来是磁盘空间不足的问题,并且动态代理程序集无法写入磁盘。只是意识到了这一点,因为当它短暂出现时,我偶然发现了Windows的“磁盘空间不足”图标。 :-P
清除一堆(大)临时文件可以解决问题。
,我今天遇到了同样的问题,不喜欢提供的解决方案。这些曾经是:
删除了自己的Castle.Core版本,并删除了强大的命名代码。参考
修改文件夹的权限。参考:这个问题
更改加密密钥存储。参考:这个问题
以下内容可能是一个肮脏的技巧,但效果很好,我不必向IT部门解释为什么我要重新配置所有最终用户计算机。
/// <summary>
/// Ensures that NHibernate creates no strong named proxy assemblies.
/// Assumes usage of Castle.DynamicProxy. Needs to be revisited
/// after update of NHibernate or Castle.Proxy!
/// </summary>
private static void EnsureNHibernateCreatesNoStrongNamedProxyAssemblies()
{
if (!StrongNameUtil.CanStrongNameAssembly)
{
Logger.Debug(\"NHibernate is not trying to strong name assemblies.\" +
\"No action needed.\");
return;
}
const string FieldName = \"canStrongNameAssembly\";
var type = typeof(StrongNameUtil);
var field = type.GetField(FieldName,BindingFlags.Static
| BindingFlags.NonPublic);
if (field == null)
{
Logger.Warn(
\"No field with the name {0} exists in the type {1}.\"
+ \"Can\'t change NHibernate to use weak named proxy assemblies.\",FieldName,type);
return;
}
field.SetValue(null,false);
if (StrongNameUtil.CanStrongNameAssembly)
{
Logger.Warn(
\"Couldn\'t change value of field {0} on type {1}. \"
+ \"NHibernate will continue to use strong named proxy assemblies.\",type);
}
else
Logger.Debug(\"Successfully changed NHibernate to use \"
+ \"weak named proxy assemblies.\");
}
只要确保在程序的开始就调用了此方法,就可以生成第一个代理。
我想真正的解决方案是升级到NHibernate 3.3,该功能现在看来不再存在此问题,但这不是当前的选择。