我试图使用InternalsVisibleTo
集属性,使在.NET类库我的单元测试项目可见我的内部类。 出于某种原因,我不断收到一个错误,指出消息:
“MyClassName”不可访问由于其保护级别
这两个组件签名和我在属性声明中列出的正确的密钥。 有任何想法吗?
我试图使用InternalsVisibleTo
集属性,使在.NET类库我的单元测试项目可见我的内部类。 出于某种原因,我不断收到一个错误,指出消息:
“MyClassName”不可访问由于其保护级别
这两个组件签名和我在属性声明中列出的正确的密钥。 有任何想法吗?
你真的确认你在属性中指定正确的公钥? 请注意,您需要指定完整的公钥,而不仅仅是公钥标记。 它看起来是这样的:
[assembly: InternalsVisibleTo("MyFriendAssembly,
PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73
F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66
A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519
674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C140
6E2F553073FF557D2DB6C5")]
这是320个左右的十六进制数字。 不知道为什么你需要指定完整的公钥 - 只有被其他程序集引用中使用它会更容易有人恶搞朋友组装的身份公钥标记可能。
另一种可能的“疑难杂症”:您在指定的朋友组件的名称InternalsVisibleToAttribute
必须像在朋友的项目属性(在应用程序选项卡)你的朋友程序集的名称完全匹配。
就我而言,我有一个项目Thingamajig
和配套项目ThingamajigAutoTests
(名称变更为保护有罪),这两个生产无符号组件。 我适当添加的属性[assembly: InternalsVisibleTo( "ThingamajigAutoTests" )]
到Thingamajig \ AssemblyInfo.cs文件,并注释掉AssemblyKeyFile
和AssemblyKeyName
属性如上所述。 该Thingamajig
项目建得很好,但它的内部成员顽固地拒绝在自动测试项目展现出来。
很多挠头之后,我复查了ThingamajigAutoTests
项目属性,并发现该程序集的名称被指定为“ThingamajigAutoTests.dll”。 宾果-我添加了“.DLL”扩展程序集名称在InternalsVisibleTo
属性,碎片落入地方。
有时,它是微不足道的事情......
如果您的组件没有签名,但您仍然得到同样的错误,请检查您的AssemblyInfo.cs文件进行以下任一线路:
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
属性选项卡仍然会显示你的组件,无符号出现这些线条,无论(或两者)都存在,但InternalsVisibleTo属性对待与同样强烈签署这些线的装配。 简单地删除(或注释掉)这些行,它应该很好地工作适合你。
值得注意的是,如果“朋友”(测试)组装它是用C ++ / CLI,而不是C#/ VB.Net,那么你需要使用以下命令:
#using "AssemblyUnderTest.dll" as_friend
而不是一个项目引用或通常#using
语句。 出于某种原因,没有办法在项目引用UI做到这一点。
您可以使用AssemblyHelper工具 ,将产生InternalsVisibleTo语法为您服务。 这里是链接到最新版本 。 只要注意,它仅适用于强命名程序集。
下面是我用它来快速生成此属性的宏。 它有点哈克,但它的作品。 在我的机器。 当最新的符号二进制是/bin/debug
。 等含糊等等。总之,你可以看到它是如何得到钥匙,这样会给你一个提示。 修复/改善作为你的时间允许。
Sub GetInternalsVisibleToForCurrentProject()
Dim temp = "[assembly: global::System.Runtime.CompilerServices." + _
"InternalsVisibleTo(""{0}, publickey={1}"")]"
Dim projs As System.Array
Dim proj As Project
projs = DTE.ActiveSolutionProjects()
If projs.Length < 1 Then
Return
End If
proj = CType(projs.GetValue(0), EnvDTE.Project)
Dim path, dir, filename As String
path = proj.FullName
dir = System.IO.Path.GetDirectoryName(path)
filename = System.IO.Path.GetFileNameWithoutExtension(path)
filename = System.IO.Path.ChangeExtension(filename, "dll")
dir += "\bin\debug\"
filename = System.IO.Path.Combine(dir, filename)
If Not System.IO.File.Exists(filename) Then
MsgBox("Cannot load file " + filename)
Return
End If
Dim assy As System.Reflection.Assembly
assy = System.Reflection.Assembly.Load(filename)
Dim pk As Byte() = assy.GetName().GetPublicKey()
Dim hex As String = BitConverter.ToString(pk).Replace("-", "")
System.Windows.Forms.Clipboard.SetText(String.Format(temp, assy.GetName().Name, hex))
MsgBox("InternalsVisibleTo attribute copied to the clipboard.")
End Sub
您需要使用的输入/输出:编译友集(即不包含InternalsVisibleTo属性的组件)时,编译器开关。
编译器需要知道组件的名称,以便在编译对确定得到的组件应被视为一个朋友组装。
除了上述所有,当一切似乎是正确的,但朋友组装顽固地拒绝看到任何内部, 重新加载解决方案或重新启动Visual Studio可以解决这个问题。
在使用VS.Net 2015年我的情况,我需要签订两个组件(如至少1个总成应签署或你想引用你的程序集的公钥)。
我的项目没有使用签名的。 于是我开始加入了符号键到我的测试库和期运用的InternalsVisibleTo属性在我的项目的基础库。 但VS.Net总是解释它无法访问朋友的方法。
当我开始签署基础库(也可以是同一个或另一个号键 - 只要你做的签署基础库),VS.Net是马上能按预期运行。
以公钥以前的答案的工作:(Visual Studio的2015年:必须在同一行,否则就抱怨说,装配基准无效或不能引用的公钥不工作)
[assembly: InternalsVisibleTo("NameSpace.MyFriendAssembly, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C1406E2F553073FF557D2DB6C5")]
由于@Joe
为了让朋友组装的公钥:
sn -Tp path\to\assembly\MyFriendAssembly.dll
内Developper命令提示符(启动>程序>的Visual Studio 2015年> Visual Studio工具>为VS2015开发人员命令提示符)。 由于@Ian G.
虽然,最终的触摸,使得它为我的工作上面是签我的朋友库项目共享库的项目签署了同样的方式后。 由于这是一个新的测试库,它尚未签署。
您需要生成用于装配的新的完整的公钥,然后指定属性组装。
[assembly: InternalsVisibleTo("assemblyname,
PublicKey="Full Public Key")]
按照下面的MSDN步骤来为从Visual Studio装配新的完整的公钥。
于获取大会公钥项添加到工具菜单
在Visual Studio中,单击工具菜单上的外部工具 。
在外部工具对话框中,单击添加 ,然后输入获取大会公钥在标题框中。
通过浏览到SN.EXE填充命令框。 它通常安装在以下位置:C:\ Program Files文件(x86)的\微软的SDK \的Windows \ v7.0a \ BIN \ 64 \ SN.EXE。
在参数框中,键入以下(区分大小写):$ -TP(TARGETPATH)。 选择使用输出窗口复选框。
单击确定 。 新命令添加到工具菜单。
当你需要您正在开发的程序集的公钥标记,单击工具菜单上获取大会公钥命令,公钥标记出现在输出窗口。
这可能是棘手的另一种可能的追查,这取决于你的代码是怎么写的。
例如:
// In X
internal static class XType
{
internal static ZType GetZ() { ... }
}
// In Y:
object someUntypedValue = XType.GetZ();
// In Z:
internal class ZType { ... }
如果您有它这样写上面,在那里你不能直接Y中提到ZType,已经增加y为x的朋友后,你可能会迷惑为什么你的代码仍然不能编译。
编译错误肯定可以在这种情况下更有帮助。
仅适用,如果你想保持无符号组件为无符号组件(和不愿签字的几个原因):
还有另外一点:如果你编译从VS.Net您的基本库到本地目录,预期它可能工作。
但是:只要您编译基本库到网络驱动器,安全策略应用并不能成功加载的程序集。 这再次引起VS.NET或编译器的公钥匹配检测的时候失败。
最后,它可以使用无符号的组件: https://msdn.microsoft.com/en-us/library/bb384966.aspx您必须确保两个组件都没有签署大会属性必须是不公钥信息:
<Assembly: InternalsVisibleTo("friend_unsigned_B")>
我写这篇文章是出于无奈。 请确保您授权访问,你想到的是命名大会。
我改名为我的项目,但这不会自动更新程序集名称。 右键点击您的项目,然后单击属性 。 在应用程序 ,确保大会名称和默认命名空间是你所期望的。
我有同样的问题。 该解决方案中没有工作。
最终发现了问题,是由于X类明确实现的接口Y,这是内部的。
该方法X.InterfaceMethod是不可用的,虽然我不知道为什么。
解决的办法是投(X为YourInterface).InterfaceMethod测试库,然后事情的来龙去脉。
作为一个侧面说明,如果你想轻松获得公共密钥,而不必使用SN,并找出它的选项,你可以下载方便的程序在这里 。 它不仅决定了公共密钥,但也创造了“集结号:InternalsVisibleTo ......”行准备被复制到剪贴板并粘贴到你的代码。
我刚刚解决了与类似的问题InternalsVisibleTo
属性。 一切似乎正确的,我无法弄清楚,为什么内部类我的目标仍然无法访问。
从上部的密钥的情况下改变为小写固定的问题。
如果你有超过1个引用的程序集 - 检查所有必要的组件都InternalsVisibleTo属性。 有时,这不是很明显,并没有消息,你有这个属性添加到别的一个组件。
1 -登录测试项目:在Visual Studio中去测试项目的属性窗口,并通过检查与签名选项卡相同短语的复选框登录大会 。
2 -创建测试项目一个公钥:打开Visual Studio命令提示符(为2017年VS例如开发者命令提示符)。 转到该测试项目的.dll文件所在的文件夹。 通过创建一个SN.EXE公共密钥:
SN -tp TestProject.dll
注意参数是-TP,但不-TP。
3-介绍公钥对项目进行测试:转到AssemblyInfo.cs文件在项目中进行测试 ,并与在上一步中创建的公钥加入这一行:
[组件:InternalsVisibleTo(” TestProjectAssemblyName, 公钥 = 2066212d128683a85f31645c60719617ba512c0bfdba6791612ed56350368f6cc40a17b4942ff16cda9e760684658fa3f357c137a1005b04cb002400000480000094000000060200000024000052534131000400000100010065fe67a14eb30ffcdd99880e9d725f04e5c720dffc561b23e2953c34db8b7c5d4643f476408ad1b1e28d6bde7d64279b0f51bf0e60be2d383a6c497bf27307447506b746bd2075" )]
不要忘记与你来代替上述公钥。
4-使私有方法内部:在项目进行测试改变方法的访问修饰符内部。
内部静态无效DoSomething的(){...}