Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 内部可视属性isn';行不通_.net_Attributes_Internalsvisibleto - Fatal编程技术网

.net 内部可视属性isn';行不通

.net 内部可视属性isn';行不通,.net,attributes,internalsvisibleto,.net,Attributes,Internalsvisibleto,我试图使用InternalsVisibleToassembly属性使.NET类库中的内部类对我的单元测试项目可见。出于某种原因,我不断收到一条错误消息,上面写着: “MyClassName”由于其保护级别而不可访问 两个程序集都已签名,并且我在属性声明中列出了正确的密钥。有什么想法吗?编译friend程序集时,需要使用/out:compiler开关 不包含InternalsVisibleTo属性) 编译器需要知道正在编译的程序集的名称,以便确定生成的程序集是否应被视为友元程序集 您是否绝对确定在

我试图使用
InternalsVisibleTo
assembly属性使.NET类库中的内部类对我的单元测试项目可见。出于某种原因,我不断收到一条错误消息,上面写着:

“MyClassName”由于其保护级别而不可访问


两个程序集都已签名,并且我在属性声明中列出了正确的密钥。有什么想法吗?

编译friend程序集时,需要使用/out:compiler开关 不包含InternalsVisibleTo属性)


编译器需要知道正在编译的程序集的名称,以便确定生成的程序集是否应被视为友元程序集

您是否绝对确定在属性中指定了正确的公钥? 请注意,您需要指定完整公钥,而不仅仅是公钥令牌。它看起来像:

[assembly: InternalsVisibleTo("MyFriendAssembly,
PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73
F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66
A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519
674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C140
6E2F553073FF557D2DB6C5")]

大约是320个十六进制数字。不确定为什么需要指定完整公钥-可能仅使用在其他程序集引用中使用的公钥令牌,这将更容易让人伪造好友程序集的身份。

值得注意的是,如果“好友”(测试)程序集是用C++/CLI而不是C#/VB.NET编写的,您需要使用以下各项:

#using "AssemblyUnderTest.dll" as_friend

使用语句代替项目参考或通常的
#。由于某些原因,在项目引用UI中无法执行此操作。

您可以使用它为您生成InternalsVisibleTo语法。给你。只需注意,它仅适用于强名称程序集。

如果程序集未签名,但仍然出现相同的错误,请检查AssemblyInfo.cs文件中的以下行:

[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

如果这些行中有一行(或两行)存在,则“属性”选项卡仍会将程序集显示为未签名,但InternalsVisibleTo属性将具有这些行的程序集视为强签名。只需删除(或注释掉)这些行,就可以了。

下面是一个用于快速生成此属性的宏。这有点老套,但很管用。在我的机器上。当最新签名的二进制文件位于
/bin/debug
中时。等等,模棱两可等等。无论如何,你可以看到它是如何得到钥匙的,这会给你一个提示。在您的时间允许的情况下修复/改进

子GetInternalsVisibleTorCurrentProject()
Dim temp=“[assembly:global::System.Runtime.CompilerServices.”_
InternalsVisibleTo(“{0},publickey={1}”)]
Dim projs作为System.Array
作为项目的Dim项目
projs=DTE.ActiveSolutionProjects()
如果项目长度小于1,则
返回
如果结束
proj=CType(projs.GetValue(0),EnvDTE.Project)
Dim path、dir、文件名为字符串
path=proj.FullName
dir=System.IO.Path.GetDirectoryName(路径)
filename=System.IO.Path.GetFileNameWithoutExtension(路径)
filename=System.IO.Path.ChangeExtension(文件名为“dll”)
dir+=“\bin\debug\”
filename=System.IO.Path.Combine(目录,文件名)
如果System.IO.File.Exists(文件名)不存在,则
MsgBox(“无法加载文件”+文件名)
返回
如果结束
尺寸总成为System.Reflection.Assembly
assy=System.Reflection.Assembly.Load(文件名)
Dim pk作为字节()=assy.GetName().GetPublicKey()
Dim hex As String=BitConverter.ToString(主键)。替换(“-”,”)
System.Windows.Forms.Clipboard.SetText(String.Format(temp,assy.GetName().Name,hex))
MsgBox(“InternalsVisibleTo属性已复制到剪贴板。”)
端接头

作为旁注,如果您想轻松获取公钥,而不必使用sn并确定其选项,您可以下载handy程序。它不仅确定公钥,还创建“assembly:InternalsVisibleTo…”行,准备复制到剪贴板并粘贴到代码中。

我刚刚解决了
InternalsVisibleTo
属性的类似问题。一切似乎都正常,我不明白为什么我瞄准的内部类仍然无法访问

将键的大小写从大写改为小写解决了此问题

另一个可能的“问题”:您在
InternalsVisibleToAttribute
中指定的好友程序集的名称必须与好友的项目属性(在应用程序选项卡中)中显示的好友程序集的名称完全匹配

在我的例子中,我有一个项目
Thingamajig
和一个配套项目
ThingamajigAutoTests
(名称更改以保护罪犯),这两个项目都产生了未签名的程序集。我适时地将属性
[assembly:InternalsVisibleTo(“ThingamajigAutoTests”)]
添加到Thingamajig\AssemblyInfo.cs文件中,并注释掉上面提到的
AssemblyKeyFile
AssemblyKeyName
属性。Thingamajig项目建设得很好,但其内部成员顽固地拒绝参加自动测试项目

在费尽心思之后,我重新检查了
ThingamajigAutoTests
项目属性,发现程序集名称被指定为“ThingamajigAutoTests.dll”。宾果-我在
InternalsVisibleTo
属性中向程序集名称添加了“.dll”扩展名,这些部分就就位了


有时,这是最微不足道的事情…

除了上述所有内容之外,当所有内容似乎都是正确的,但好友程序集顽固地拒绝查看任何内部内容时,重新加载解决方案或重新启动Visual Studio可以解决问题。

先前使用PublicKey的答案有效:(Visual Studio 2015:需要在一行上,否则它会抱怨程序集引用无效或无法引用。PublicKeyToken不起作用)

感谢@Joe


要获取好友程序集的公钥,请执行以下操作:

sn -Tp path\to\assembly\MyFriendAssembly.dll
在显影器命令提示符内(启动>程序>可视S
sn -Tp path\to\assembly\MyFriendAssembly.dll
[assembly: InternalsVisibleTo("assemblyname,
PublicKey="Full Public Key")]
// In X
internal static class XType
{
    internal static ZType GetZ() { ... }
}

// In Y:
object someUntypedValue = XType.GetZ();

// In Z:
internal class ZType { ... }