문제

나는 InternalsVisibleTo .NET 클래스 라이브러리의 내부 클래스를 내 단위 테스트 프로젝트에 표시할 수 있도록 합니다.어떤 이유로 다음과 같은 오류 메시지가 계속 나타납니다.

보호 수준으로 인해 'MyClassName'에 액세스할 수 없습니다.

두 어셈블리 모두 서명되었으며 속성 선언에 올바른 키가 나열되어 있습니다.어떤 아이디어가 있나요?

도움이 되었습니까?

해결책

속성에 올바른 공개 키가 지정되어 있다고 확신하시나요?공개 키 토큰뿐만 아니라 전체 공개 키를 지정해야 합니다.다음과 같습니다.

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

320자리 정도의 16진수입니다.전체 공개 키를 지정해야 하는 이유를 잘 모르겠습니다. 다른 어셈블리 참조에 사용되는 공개 키 토큰만 사용하면 누군가가 친구 어셈블리의 ID를 스푸핑하는 것이 더 쉬울 수 있습니다.

다른 팁

또 다른 가능한 "문제":지정한 친구 어셈블리의 이름 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#/VB.Net이 아닌 C++/CLI로 작성된 경우 다음을 사용해야 한다는 점은 주목할 가치가 있습니다.

#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

/out을 사용해야 합니다.컴파일러 스위치 친구 어셈블리를 컴파일 할 때 (InternalSvisibleto 속성이 포함되지 않은 어셈블리).

컴파일러는 결과 어셈블리가 프렌드 어셈블리로 간주되어야 하는지 결정하기 위해 컴파일되는 어셈블리의 이름을 알아야 합니다.

위의 모든 것 외에도 모든 것이 옳은 것처럼 보이지만 친구 모임은 완고하게 내부를 보지 않을 때, 솔루션 다시 로드 또는 Visual Studio 다시 시작 문제를 해결할 수 있습니다.

내 경우에는 VS.Net 2015를 사용하여 서명해야 했습니다. 둘 다 어셈블리(최소 1개의 어셈블리에 서명해야 하거나 어셈블리의 공개 키를 참조하려는 경우)

내 프로젝트에서는 서명을 전혀 사용하지 않았습니다.그래서 테스트 라이브러리에 서명 키를 추가하고 프로젝트의 기본 라이브러리에서 InternalsVisibleTo-Attribute를 사용하기 시작했습니다.그러나 VS.Net은 항상 친구 메소드에 접근할 수 없다고 설명했습니다.

기본 라이브러리에 서명하기 시작했을 때(기본 라이브러리에 서명하는 한 동일하거나 다른 서명 키일 수 있음) VS.Net은 즉시 예상대로 작동할 수 있었습니다.

PublicKey를 사용한 이전 답변은 다음과 같습니다.(비주얼 스튜디오 2015:한 줄에 있어야 합니다. 그렇지 않으면 어셈블리 참조가 유효하지 않거나 참조할 수 없다고 불평합니다.PublicKeyToken이 작동하지 않았습니다)

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

@Joe 덕분에

친구 어셈블리의 공개 키를 얻으려면:

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

개발자 명령 프롬프트 내부(시작 > 프로그램 > Visual Studio 2015 > Visual Studio 도구 > VS2015용 개발자 명령 프롬프트)@Ian G에게 감사드립니다.

하지만 위의 작업 이후 저에게 도움이 된 마지막 작업은 공유할 도서관 프로젝트에 서명하는 것과 같은 방식으로 내 친구 도서관 프로젝트에 서명하는 것이었습니다.새로운 테스트 라이브러리였기 때문에 아직 서명되지 않았습니다.

어셈블리에 대한 새로운 전체 공개 키를 생성한 다음 어셈블리에 대한 특성을 지정해야 합니다.

[assembly: InternalsVisibleTo("assemblyname,
PublicKey="Full Public Key")]

아래를 따르십시오 MSDN Visual Studio에서 어셈블리에 대한 새로운 전체 공개 키를 생성하는 단계입니다.

도구 메뉴에 어셈블리 공개 키 가져오기 항목을 추가하려면

Visual Studio에서 외부 도구 도구 메뉴에서

외부 도구 대화 상자에서 추가하다 제목 상자에 Get Assembly Public Key를 입력합니다.

sn.exe를 찾아 명령 상자를 채웁니다.일반적으로 다음 위치에 설치됩니다. C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0a\Bin\x64\sn.exe.

인수 상자에 다음을 입력합니다(대소문자 구분). -Tp $(대상 경로).출력 창 사용 확인란을 선택합니다.

딸깍 하는 소리 좋아요.새 명령이 도구 메뉴에 추가되었습니다.

개발 중인 어셈블리의 공개 키 토큰이 필요할 때마다 도구 메뉴에서 어셈블리 공개 키 가져오기 명령을 클릭하면 공개 키 토큰이 출력 창에 나타납니다.

코드 작성 방법에 따라 추적하기 까다로울 수 있는 또 다른 가능성입니다.

  1. 다른 어셈블리 Y에서 X에 정의된 내부 메서드를 호출하고 있습니다.
  2. 메소드 서명은 Z에 정의된 내부 유형을 사용합니다.
  3. 그런 다음 X와 Z에 [InternalsVisibleTo]를 추가해야 합니다.

예를 들어:

// In X
internal static class XType
{
    internal static ZType GetZ() { ... }
}

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

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

위와 같이 작성하고 Y에서 직접 ZType을 참조하지 않고 X의 친구로 Y를 추가한 경우 코드가 여전히 컴파일되지 않는 이유가 무엇인지 알 수 없습니다.

이 경우 컴파일 오류가 확실히 더 도움이 될 수 있습니다.

서명되지 않은 어셈블리를 서명되지 않은 어셈블리로 유지하려는 경우(그리고 여러 가지 이유로 서명하고 싶지 않은 경우)에만 적용됩니다.

또 다른 요점이 있습니다.VS.Net에서 로컬 디렉터리로 기본 라이브러리를 컴파일하면 예상대로 작동할 수 있습니다.

하지만:기본 라이브러리를 네트워크 드라이브로 컴파일하자마자 보안 정책이 적용되고 어셈블리가 성공적으로 로드될 수 없습니다.이로 인해 VS.NET 또는 컴파일러가 PublicKey 일치를 확인할 때 다시 실패하게 됩니다.

마지막으로 서명되지 않은 어셈블리를 사용할 수 있습니다.https://msdn.microsoft.com/en-us/library/bb384966.aspx두 어셈블리 모두 서명되지 않도록해야하며 어셈블리 속성에 공개 키 정보가 없어야합니다.

<Assembly: InternalsVisibleTo("friend_unsigned_B")>

답답한 마음에 이 글을 쓰고 있습니다.액세스 권한을 부여하려는 어셈블리의 이름이 예상한 대로 지정되었는지 확인하세요.

프로젝트 이름을 바꾸었지만 어셈블리 이름이 자동으로 업데이트되지 않습니다.프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성.아래에 애플리케이션, 다음을 확인하세요. 어셈블리 이름 그리고 기본 네임스페이스 당신이 기대하는 것입니다.

나는 같은 문제가 있었다.어떤 솔루션도 효과가 없었습니다.

결국 이 문제는 클래스 X가 내부 인터페이스 Y를 명시적으로 구현했기 때문에 발생한 것임을 발견했습니다.

X.InterfaceMethod 메서드를 사용할 수 없지만 이유는 모르겠습니다.

해결책은 테스트 라이브러리에서 (X를 YourInterface로).InterfaceMethod를 캐스팅하는 것이었고 모든 것이 작동했습니다.

참고로, sn을 사용하지 않고도 공개 키를 쉽게 얻고 해당 옵션을 알아보려면 편리한 프로그램을 다운로드할 수 있습니다. 여기.공개 키를 결정할 뿐만 아니라 "어셈블리:InternalsVisibleTo...' 줄을 클립보드에 복사하여 코드에 붙여 넣을 준비가 되었습니다.

방금 비슷한 문제를 해결했습니다. InternalsVisibleTo 기인하다.모든 것이 옳은 것 같았고 왜 내가 목표로 삼고 있던 내부 클래스에 여전히 접근할 수 없는지 알 수 없었습니다.

키의 대소문자를 대문자에서 소문자로 변경하면 문제가 해결되었습니다.

참조된 어셈블리가 2개 이상인 경우 필요한 모든 어셈블리에 InternalsVisibleTo 특성이 있는지 확인하세요.때로는 이 특성을 다른 어셈블리에 추가해야 한다는 메시지가 명확하지도 않고 메시지도 표시되지 않는 경우도 있습니다.

1- 테스트 프로젝트에 서명합니다. Visual Studio에서 속성 창으로 이동합니다. 테스트 프로젝트 그리고 의회에 서명하다 동일한 문구가 포함된 확인란을 선택하면 서명 탭.

2- 테스트 프로젝트에 대한 PublicKey를 만듭니다. Visual Studio 명령 프롬프트를 엽니다(예:VS 2017용 개발자 명령 프롬프트)..dll 파일이 있는 폴더로 이동합니다. 테스트 프로젝트 존재합니다.sn.exe를 통해 공개 키를 생성합니다.

sn -Tp TestProject.dll

인수는 -Tp이지만 -tp는 아닙니다.

3- 테스트할 프로젝트에 PublicKey를 도입합니다. AssemblyInfo.cs 파일로 이동합니다. 테스트할 프로젝트 이전 단계에서 생성한 PublicKey를 사용하여 다음 줄을 추가합니다.

[집회:내부VisibleTo("테스트프로젝트어셈블리이름, 공개키=2066212d128683a85f31645c60719617ba512c0bfdba6791612ed56350368f6cc40a17b4942ff16cda9e760684658fa3f357c137a1005b04cb0024000004800000 94000000060200000024000052534131000400000100010065fe67a14eb30ffcdd99880e9d725f04e5c720dffc561b23e2953c34db8b7c5d4643f476408ad1b1e28d 6bde7d64279b0f51bf0e60be2d383a6c497bf27307447506b746bd2075")]

위의 PublicKey를 귀하의 것으로 바꾸는 것을 잊지 마십시오.

4- 개인 메소드를 내부로 만드십시오. 테스트할 프로젝트에서 메서드의 액세스 한정자를 내부로 변경합니다.

내부 정적 무효 DoSomething(){...}

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top