Atrybut InternalsVisibleTo nie działa
Próbuję użyć atrybutu InternalsVisibleTo
assembly, aby moje wewnętrzne klasy w bibliotece klas.NET były widoczne dla mojego projektu testów jednostkowych. Z jakiegoś powodu ciągle dostaję komunikat o błędzie, który mówi:
'MyClassName' jest niedostępny ze względu na poziom ochrony
Oba zespoły są podpisane i mam poprawny klucz wymieniony w deklaracji atrybutów. Jakieś pomysły?
19 answers
Czy jesteś absolutnie pewien, że masz poprawny klucz publiczny określony w atrybutie? Pamiętaj, że musisz podać pełny klucz publiczny, a nie tylko token klucza publicznego. Wygląda to tak:
[assembly: InternalsVisibleTo("MyFriendAssembly,
PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73
F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66
A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519
674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C140
6E2F553073FF557D2DB6C5")]
To jakieś 320 cyfr szesnastkowych. Nie wiem, dlaczego musisz podać pełny klucz publiczny - prawdopodobnie używając tylko tokena klucza publicznego, który jest używany w innych referencjach do asemblera, byłoby łatwiej komuś sfałszować tożsamość asemblera znajomego.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-02 21:12:44
Inny możliwy "mam cię": nazwa zespołu znajomego, który podałeś w InternalsVisibleToAttribute
, musi dokładnie pasować do nazwy zespołu znajomego, jak pokazano we właściwościach projektu znajomego (w zakładce aplikacja).
W moim przypadku, miałem projekt Thingamajig
i projekt towarzyszący ThingamajigAutoTests
(nazwy zmienione w celu ochrony winnych), które oba produkowały niepodpisane zespoły. Dodałem atrybut [assembly: InternalsVisibleTo( "ThingamajigAutoTests" )]
do thingamajig\AssemblyInfo.plik cs i skomentował AssemblyKeyFile
i AssemblyKeyName
atrybuty jak wspomniano powyżej. Projekt Thingamajig
był dobrze zbudowany, ale jego członkowie wewnętrzni uparcie odmawiali pokazania się w projekcie autotest.
Po długim zadrapaniu głowy, ponownie sprawdziłem właściwości projektu ThingamajigAutoTests
i odkryłem, że nazwa zestawu została określona jako " ThingamajigAutoTests.dll". Bingo - dodałem"dll " rozszerzenie do nazwy złożenia w atrybutie InternalsVisibleTo
, a kawałki spadły na swoje miejsce.
Czasami to najmniejsze rzeczy...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 18:01:04
Jeśli Twoje zespoły nie są podpisane, ale nadal masz ten sam błąd, sprawdź swoje AssemblyInfo.plik cs dla jednej z następujących linii:
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
Zakładka properties nadal będzie wyświetlać skład jako niepodpisany, jeśli któryś z tych wierszy (lub oba) są obecne, ale atrybut InternalsVisibleTo traktuje skład z tymi wierszami jako silnie podpisany. Po prostu usuń (lub skomentuj) te linie, a to powinno działać dobrze dla Ciebie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-29 16:54:46
Warto zauważyć, że jeśli assembly" friend " (testy) jest napisany w C++ / CLI, a nie w C# / VB. Net, to należy użyć następującego:
#using "AssemblyUnderTest.dll" as_friend
Zamiast odniesienia do projektu lub zwykłej deklaracji #using
. Z jakiegoś powodu nie ma sposobu, aby to zrobić w interfejsie odniesienia do projektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 12:56:28
Możesz użyć narzędzia AssemblyHelper , które wygeneruje dla ciebie wewnętrzną składnię. Oto link do najnowszej wersji . Zauważ, że działa tylko dla silnie nazwanych zespołów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 16:50:45
Oto makro, którego używam do szybkiego wygenerowania tego atrybutu. Jest trochę szorstki, ale działa. Na mojej maszynie. Gdy ostatni podpisany plik binarny znajduje się w /bin/debug
. Itd. W każdym razie, możesz zobaczyć, jak dostaje klucz, więc to da ci wskazówkę. Naprawić / poprawić jak Twój czas pozwala.
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
Oprócz wszystkich powyższych, gdy wszystko wydaje się być poprawne, ale przyjaciel assembly uparcie odmawia zobaczenia jakichkolwiek wewnętrznych, przeładowanie rozwiązania lub ponowne uruchomienie Visual Studio może rozwiązać problem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 12:03:10
Musisz użyć przełącznika / out: compiler podczas kompilacji friend assembly (assembly, który nie zawiera atrybutu InternalsVisibleTo).
Kompilator musi znać nazwę kompilowanego zestawu, aby określić, czy Wynikowy zestaw powinien być uważany za zestaw przyjacielski.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-20 03:16:25
Wymagane jest wygenerowanie nowego pełnego klucza publicznego dla złożenia, a następnie określenie atrybutu do złożenia.
[assembly: InternalsVisibleTo("assemblyname,
PublicKey="Full Public Key")]
Wykonaj poniższe kroki MSDN , aby wygenerować nowy pełny klucz publiczny dla złożenia z programu visual studio.
Aby dodać pozycję klucz publiczny Get Assembly do menu Narzędzia
W Visual Studio kliknij External Tools w menu Narzędzia.
W oknie dialogowym Narzędzia zewnętrzne kliknij Dodaj i wprowadź Get Assembly Public Klucz w polu Tytuł.
Wypełnij pole poleceń, przeglądając sn.exe. Zazwyczaj jest instalowany w następującej lokalizacji: C:\Program Files (x86) \ Microsoft SDKs \ Windows \ v7. 0a \ Bin \ x64 \ sn.exe .
W polu Arguments wpisz następujący (rozróżniający wielkość liter): - TP $(TargetPath) . Zaznacz pole wyboru Użyj okna wyjścia.
Kliknij OK . Nowe polecenie jest dodawane do menu Narzędzia.
Gdy potrzebujesz Tokena klucza publicznego zgromadzenia, jesteś rozwijając, kliknij polecenie Get Assembly public Key w menu Narzędzia, a token klucza publicznego pojawi się w oknie wyjściowym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-18 18:13:59
W moim przypadku za pomocą VS.Net 2015, musiałem podpisać oba zespoły (Jeśli co najmniej 1 Zgromadzenie ma być podpisane lub chcesz odwołać się do klucza publicznego swojego zgromadzenia).
Mój projekt w ogóle nie używał podpisywania. Zacząłem więc dodawać klucz znakowy do mojej biblioteki testowej i używać atrybutu InternalsVisibleTo w bibliotece bazowej mojego projektu. Ale VS.Net zawsze tłumaczył, że nie ma dostępu do metod przyjacielskich.
Kiedy zacząłem podpisywać bibliotekę bazową (może być taka sama lub kolejny klucz znakowy - o ile podpiszesz bibliotekę bazową), VS.Net natychmiast był w stanie pracować zgodnie z oczekiwaniami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-25 15:36:44
Poprzednie odpowiedzi z PublicKey działały: (Visual Studio 2015: musi być w jednej linii, w przeciwnym razie narzeka, że odniesienie do montażu jest nieprawidłowe lub nie może się odwołać. PublicKeyToken nie działa)
[assembly: InternalsVisibleTo("NameSpace.MyFriendAssembly, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C1406E2F553073FF557D2DB6C5")]
Dzięki @ Joe
Aby uzyskać klucz publiczny zespołu znajomego:
sn -Tp path\to\assembly\MyFriendAssembly.dll
Wewnątrz wiersza polecenia programisty (uruchamianie > programy > Visual Studio 2015 > narzędzia Visual Studio > Wiersz polecenia programisty dla VS2015). Dzięki @ Ian G.
Chociaż, ostatnim akcentem, który sprawił, że działał dla mnie po powyższym, było podpisanie projektu biblioteki mojego przyjaciela w taki sam sposób, w jaki projekt biblioteki do udostępnienia jest podpisany. Ponieważ była to nowa biblioteka testowa, nie została jeszcze podpisana.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 15:57:50
Kolejna możliwość, która może być trudna do wyśledzenia, w zależności od tego, jak jest napisany kod.
- wywołujesz wewnętrzną metodę zdefiniowaną w X z innego zbioru Y
- podpis metody wykorzystuje typy wewnętrzne zdefiniowane w Z
- Następnie musisz dodać [InternalsVisibleTo] W X I W z
Na przykład:
// In X
internal static class XType
{
internal static ZType GetZ() { ... }
}
// In Y:
object someUntypedValue = XType.GetZ();
// In Z:
internal class ZType { ... }
Jeśli masz to napisane jak wyżej, gdzie nie odnosisz się bezpośrednio do ZType w Y, po dodaniu Y jako przyjaciela X, możesz może być dziwne, dlaczego twój kod nadal nie jest kompilowany.
Błąd kompilacji może być zdecydowanie bardziej pomocny w tym przypadku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-08 00:10:49
Piszę to z frustracji. Upewnij się, że zespół, do którego przyznajesz dostęp, jest nazwany zgodnie z oczekiwaniami.
Zmieniłem nazwę projektu, ale to nie powoduje automatycznej aktualizacji nazwy zestawu. Kliknij prawym przyciskiem myszy projekt i kliknij Właściwości. W aplikacji Upewnij się, że Nazwa zestawu i domyślna Przestrzeń nazw są tym, czego oczekujesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 00:25:44
Stosuje się tylko wtedy, gdy chcesz zachować niepodpisane zespoły jako niepodpisane zespoły (i nie chcesz go podpisywać z kilku powodów):
Jest jeszcze jedna kwestia: jeśli skompilujesz swoją bibliotekę bazową z VS.Net do katalogu lokalnego, może działać zgodnie z oczekiwaniami.
Ale: gdy tylko skompilujesz bibliotekę bazową na dysku sieciowym, obowiązują zasady bezpieczeństwa i nie można załadować zestawu. To znowu powoduje VS.NET lub kompilator, który nie sprawdzi się przy sprawdzaniu mecz.
Wreszcie, możliwe jest użycie niepodpisanych zestawów: https://msdn.microsoft.com/en-us/library/bb384966.aspx Musisz upewnić się, że oba zespoły nie są podpisane A atrybut Assembly musi być bez Informacji Publicznej:
<Assembly: InternalsVisibleTo("friend_unsigned_B")>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-25 15:34:20
Miałem ten sam problem. Żadne z rozwiązań nie zadziałało.
Ostatecznie odkryłem, że problem był spowodowany jawnie implementującym interfejs Y klasy X, który jest wewnętrzny.
Metoda X. InterfaceMethod była niedostępna, choć nie mam pojęcia dlaczego.
Rozwiązaniem było rzucenie (X jako Twejinterface).InterfaceMethod w bibliotece testowej, a potem wszystko działało.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 15:50:16
Na marginesie, jeśli chcesz łatwo uzyskać klucz publiczny bez konieczności używania sn i poznawania jego opcji, możesz pobrać przydatny program tutaj. Nie tylko określa klucz publiczny, ale także tworzy " assembly :InternalsVisibleTo..."linia gotowa do skopiowania do schowka i wklejenia do kodu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-26 18:25:51
Właśnie rozwiązałem podobny problem z atrybutem InternalsVisibleTo
. Wszystko wydawało się w porządku i nie mogłem zrozumieć, dlaczego wewnętrzna Klasa, do której celowałem, nadal nie była dostępna.
Zmiana wielkości liter klawisza z wielkiej na małą rozwiązała problem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-26 09:20:02
Jeśli masz więcej niż 1 odwołany assembly-sprawdź, czy wszystkie niezbędne Assembly mają atrybut InternalsVisibleTo. Czasami nie jest to oczywiście, i nie ma wiadomości, że trzeba dodać ten atrybut do else jeden assembly.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 14:00:50
1- podpisz projekt testowy: w Visual Studio przejdź do okna Właściwości projektu testowego i podpisz zespół zaznaczając pole wyboru z tą samą frazą w zakładce podpisywanie .
2- Utwórz publicznie dla projektu testowego: Otwórz wiersz poleceń programu Visual Studio (np. Wiersz poleceń dewelopera dla VS 2017). Przejdź do folderu gdzie .plik dll istnieje projekt testowy. Utwórz klucz publiczny przez sn.exe:
Sn-TP TestProject.dll
Zauważ, że argumentem jest-Tp, ale nie -tp.
3- wprowadź PublicKey do testowanego projektu: Przejdź do AssemblyInfo.plik cs w projekcie do przetestowania i dodaj tę linijkę do pliku utworzonego w poprzednim kroku:
[assembly: InternalsVisibleTo ("TestProjectAssemblyName , PublicKey=2066212d128683a85f31645c60719617ba512c0bfdba6791612ed56350368f6cc40a17b4942ff16cda9e760684658fa3f357c137a1005b04cb002400000480000094000000060200000024000052534131000400000100010065fe67a14eb30ffcdd99880e9d725f04e5c720dffc561b23e2953c34db8b7c5d4643f476408ad1b1e28d6bde7d64279b0f51bf0e60be2d383a6c497bf27307447506b746bd2075")]
Nie zapomnij wymienić powyższej strony na swoją.
4- Uczyń metodę prywatną wewnętrzną: w projekcie do przetestowania Zmień modyfikator dostępu metody na wewnętrzny.
Internal static void DoSomething () {...}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-03 11:56:16