76

InternalsVisibleToアセンブリ属性を使用して、.NET クラス ライブラリの内部クラスを単体テスト プロジェクトに表示しようとしています。何らかの理由で、次のようなエラー メッセージが表示され続けます。

'MyClassName' は、保護レベルが原因でアクセスできません

両方のアセンブリが署名されており、属性宣言に正しいキーがリストされています。何か案は?

4

20 に答える 20

103

属性で指定された正しい公開鍵を持っていることを絶対に確信していますか? 公開鍵トークンだけでなく、完全な公開鍵を指定する必要があることに注意してください。次のようになります。

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

320 桁程度の 16 進数です。完全な公開キーを指定する必要がある理由がわかりません。おそらく、他のアセンブリ参照で使用されている公開キー トークンだけを使用すると、誰かがフレンド アセンブリの ID を簡単に偽装できる可能性があります。

于 2008-09-20T11:40:12.633 に答える
37

アセンブリが署名されていないにもかかわらず、同じエラーが発生する場合は、AssemblyInfo.cs ファイルで次の行のいずれかを確認してください。

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

これらの行のいずれか (または両方) が存在する場合、[プロパティ] タブにはアセンブリが未署名として表示されますが、InternalsVisibleTo 属性はこれらの行を含むアセンブリを強力に署名されたものとして扱います。これらの行を削除 (またはコメントアウト) するだけで、問題なく動作するはずです。

于 2010-08-29T13:09:14.877 に答える
12

「フレンド」(テスト)アセンブリがC#/VB.NETではなくC++ / CLIで記述されている場合は、次を使用する必要があることに注意してください。

#using "AssemblyUnderTest.dll" as_friend

プロジェクト参照や通常の#usingステートメントの代わりに。何らかの理由で、プロジェクト参照UIでこれを行う方法はありません。

于 2009-04-20T22:50:02.560 に答える
9

InternalsVisibleTo 構文を生成するAssemblyHelper ツールを使用できます。ここに最新バージョンへのリンクがあります。厳密な名前のアセンブリに対してのみ機能することに注意してください。

于 2010-05-10T01:23:47.067 に答える
5

この属性をすばやく生成するために使用するマクロを次に示します。少しハックですが、動作します。私のマシンで。最新の署名付きバイナリが/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
于 2012-03-22T17:36:45.837 に答える
5

上記のすべてに加えて、すべてが正しいように見えても、フレンド アセンブリが頑固に内部の表示を拒否する場合は、ソリューションを再読み込みするか、Visual Studio を再起動することで問題を解決できます。

于 2014-09-17T12:03:10.330 に答える
4

フレンド アセンブリ (InternalsVisibleTo 属性を含まないアセンブリ) をコンパイルするときは、/out: コンパイラ スイッチを使用する必要があります。

コンパイラは、結果のアセンブリがフレンド アセンブリと見なされるかどうかを判断するために、コンパイルされるアセンブリの名前を知る必要があります。

于 2008-09-20T03:16:25.513 に答える
2

PublicKey を使用した以前の回答は機能しました: (Visual Studio 2015: 1 行にする必要があります。そうしないと、アセンブリ参照が無効であるか参照できないと不平を言います。PublicKeyToken は機能しませんでした)

[assembly: InternalsVisibleTo("NameSpace.MyFriendAssembly, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C1406E2F553073FF557D2DB6C5")]

@ジョーに感謝

フレンド アセンブリの公開キーを取得するには、次のようにします。

sn -Tp path\to\assembly\MyFriendAssembly.dll

開発者コマンド プロンプト内 ([スタートアップ] > [プログラム] > [Visual Studio 2015] > [Visual Studio ツール] > [VS2015 の開発者コマンド プロンプト])。@Ian Gに感謝します。

ただし、上記の後に私にとってうまくいった最後の仕上げは、共有するライブラリのプロジェクトが署名されるのと同じ方法で、友人のライブラリ プロジェクトに署名することでした。これは新しいテスト ライブラリであるため、まだ署名されていません。

于 2015-10-14T15:57:50.527 に答える
2

コードの記述方法によっては、追跡が難しい別の可能性があります。

  1. X で定義された内部メソッドを別のアセンブリ Y から呼び出しています
  2. メソッド シグネチャは、Z で定義された内部型を使用します。
  3. 次に、[InternalsVisibleTo] を X に追加し、Z に追加する必要があります。

例えば:

// 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 のフレンドとして追加した後、なぜコードがまだコンパイルされないのか不思議に思うかもしれません。

この場合、コンパイルエラーは間違いなくより役立つ可能性があります。

于 2016-10-08T00:10:49.373 に答える
1

参照されているアセンブリが複数ある場合は、必要なすべてのアセンブリに InternalsVisibleTo 属性があることを確認してください。場合によっては、この属性を別のアセンブリに追加する必要があることは明らかではなく、メッセージもありません。

于 2018-03-29T14:00:50.667 に答える
0

InternalsVisibleTo属性に関する同様の問題を解決しました。すべてが正しいように見えましたが、私が目指していた内部クラスがまだアクセスできない理由を理解できませんでした。

キーのケースを大文字から小文字に変更すると、問題が修正されました。

于 2013-02-26T09:20:02.417 に答える
0

補足として、sn を使用せずに公開鍵を簡単に取得し、そのオプションを把握したい場合は、便利なプログラムをここからダウンロードできます。公開キーを決定するだけでなく、"assembly: InternalsVisibleTo..." 行を作成して、クリップボードにコピーしてコードに貼り付けることができます。

于 2012-04-26T18:25:51.517 に答える