วิธีการแก้ไขข้อผิดพลาด“ แอสเซมบลีที่อ้างอิงไม่มีชื่อที่รัดกุม” ข้อผิดพลาด


242

ฉันได้เพิ่มแอสเซมบลีที่ชื่ออย่างอ่อนในโครงการVisual Studio 2005ของฉัน(ซึ่งมีชื่อขอ) ตอนนี้ฉันได้รับข้อผิดพลาด:

"แอสเซมบลีที่อ้างอิง 'xxxxxxxx' ไม่มีชื่อที่รัดกุม"

ฉันจำเป็นต้องเซ็นชื่อชุดประกอบบุคคลที่สามนี้หรือไม่



1
นี่อาจฟังดูเป็นเคล็ดลับที่โง่ แต่ถ้าคุณพบว่าชุดประกอบของคุณไม่ได้รับการลงนามไม่ว่าคุณจะทำอะไรให้ตรวจสอบการตั้งค่างานสร้างของคุณ โปรดจำไว้ว่า VS ไม่ได้กำจัดสถาปัตยกรรมอื่น ๆ (CPU ใด ๆ , x64 ฯลฯ ) เมื่อคุณสร้างใหม่ / ทำความสะอาดดังนั้นคุณสามารถดู dll ที่ล้าสมัยจากสถาปัตยกรรมอื่นได้
jrh

คำตอบ:


213

เพื่อหลีกเลี่ยงข้อผิดพลาดนี้คุณสามารถ:

  • โหลดแอสเซมบลีแบบไดนามิกหรือ
  • เซ็นชื่อชุดประกอบบุคคลที่สาม

คุณจะพบคำแนะนำเกี่ยวกับการลงนามแอสเซมบลีของบุคคลที่สามใน. NET-fu: การลงนามในแอสเซมบลี Unsigned (โดยไม่ต้องเซ็นชื่อล่าช้า)(โดยไม่ชักช้าลงนาม)

การลงนามในส่วนประกอบของบุคคลที่สาม

หลักการพื้นฐานในการลงชื่อบุคคลที่สามคือ

  1. ถอดชุดประกอบโดยใช้ildasm.exeและบันทึกภาษากลาง (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. สร้างและเซ็นชื่อชุดประกอบใหม่:

    ilasm /dll /key=myKey.snk thirdPartyLib.il

แก้ไขการอ้างอิงเพิ่มเติม

ขั้นตอนข้างต้นทำงานได้ดีเว้นแต่แอสเซมบลีบุคคลที่สาม ( A.dll ) ของคุณอ้างอิงถึงไลบรารีอื่น ( B.dll ) ซึ่งจะต้องมีการเซ็นชื่อด้วย คุณสามารถแยกชิ้นส่วนสร้างใหม่และลงนามทั้งA.dllและB.dllโดยใช้คำสั่งด้านบน แต่ในขณะรันไทม์การโหลดB.dllจะล้มเหลวเพราะA.dllถูกสร้างขึ้นครั้งแรกโดยมีการอ้างอิงถึงB.dllรุ่นที่ไม่ได้ลงนาม B.dll

การแก้ไขปัญหานี้คือการแก้ไขไฟล์ IL ที่สร้างในขั้นตอนที่ 1 ด้านบน คุณจะต้องเพิ่มโทเค็นกุญแจสาธารณะของ B.dll เพื่อการอ้างอิง คุณได้รับโทเค็นนี้ด้วยการโทร

sn -Tp B.dll 

ซึ่งจะให้ผลลัพธ์ต่อไปนี้:

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.33440
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key (hash algorithm: sha1):
002400000480000094000000060200000024000052534131000400000100010093d86f6656eed3
b62780466e6ba30fd15d69a3918e4bbd75d3e9ca8baa5641955c86251ce1e5a83857c7f49288eb
4a0093b20aa9c7faae5184770108d9515905ddd82222514921fa81fff2ea565ae0e98cf66d3758
cb8b22c8efd729821518a76427b7ca1c979caa2d78404da3d44592badc194d05bfdd29b9b8120c
78effe92

Public key token is a8a7ed7203d87bc9

บรรทัดสุดท้ายมีโทเค็นกุญแจสาธารณะ จากนั้นคุณต้องค้นหา IL ของA.dllสำหรับการอ้างอิงถึงB.dllและเพิ่มโทเค็นดังนี้:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}

2
ดังนั้นการลงนามในแอสเซมบลีตัวเลือกฉันไม่ต้องการโหลดแอสเซมบลีแบบไดนามิกหรือลงนาม ฉันรู้ว่าการตั้งชื่อที่แข็งแกร่งนั้นเกี่ยวกับ Global Assembly Cache (GAC) อย่างไรก็ตามฉันไม่ต้องการให้แอสเซมบลีของฉันเป็นส่วนหนึ่งของ GAC และไม่สามารถมองเห็นได้ด้วย COM ฉันจำบางส่วนจำสิ่งที่เราอาจทำที่จะช่วยให้การใช้งานของการชุมนุมโดยไม่ต้องลงนาม มันอยู่ที่ไหนสักแห่งในคุณสมบัติของตัวเลือกหรือมากกว่านั้น ฉันอยู่นอกเส้นทางที่ต้องการจะไปทางนั้นหรือไม่?
Marcouiller จะ

27
คุณสามารถใช้ชุดประกอบที่ไม่ได้ลงชื่อถ้าชุดประกอบของคุณยังไม่ได้ลงนาม
OJ

2
ลิงก์ไปยัง. NET-fu เป็นทรัพยากรที่ยอดเยี่ยม
TheDude

2
แม้ว่าขั้นตอนข้างต้นจะทำงานในสถานการณ์ "ส่วนใหญ่" มันใช้เวลานานอย่างไม่น่าเชื่อและเกิดข้อผิดพลาดได้ง่ายและล้มเหลวด้วยการอ้างอิงชุดประกอบของเพื่อนท่ามกลางสิ่งอื่น ๆ เพียงใช้ยูทิลิตีนี้เพื่อดำเนินการทั้งหมดโดยอัตโนมัติ (เสียบแบบไม่ระบุชื่อ): stackoverflow.com/a/19459609/564726
BrutalDev

1
@Roel ฉันมีรายละเอียดกระบวนการที่นี่delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude

98

ขยายไฟล์โครงการที่ใช้โครงการที่ไม่มี "มีชื่อที่รัดกุม" และค้นหา.snkไฟล์ (.StrongNameKey)

เรียกดูไฟล์นี้ในWindows Explorer (เพื่อให้คุณทราบว่าอยู่ที่ไหน)

ย้อนกลับไปที่ Visual Studio ในโครงการที่ไม่มี "มีชื่อที่รัดกุม"

  • คลิกขวาที่ไฟล์โครงการ
  • เลือกคุณสมบัติ
  • เลือก "แท็บการลงชื่อ" (ด้านซ้าย)
  • คลิกกล่องกาเครื่องหมาย "เซ็นชื่อแอสเซมบลี"
  • จากนั้น<Browse>ไปยัง.snkไฟล์ที่คุณพบก่อนหน้านี้

นั่นควรทำเคล็ดลับ สิ่งนี้แก้ปัญหาสำหรับฉันสำหรับโครงการหนึ่งโดยใช้แบบฟอร์มภายในโครงการอื่นในโซลูชันเดียวกัน

ฉันหวังว่ามันจะช่วย


ถ้าฉันไม่ต้องการที่จะลงนามในการชุมนุมของฉันฉันจะไม่ได้ลงนามตั้งแต่ต้น!
โมฮา

หากคุณไม่พบไฟล์. snk: เปิดคุณสมบัติโครงการ (ของโครงการโดยใช้โครงการที่มีข้อผิดพลาด "ชื่อที่รัดกุม") แท็บการเซ็นชื่อ ที่นั่นคุณจะเห็นไฟล์ที่ใช้ในการเซ็นสัญญาโครงการ (ไม่ใช่ไฟล์ที่มีนามสกุล. snk เสมอไป) เพียงคัดลอกการตั้งค่านี้ไปยังโครงการอื่น
Coder14

ในฐานะที่เป็น MrOli3000 ชี้ให้เห็นมันจะทำงานเฉพาะในกรณีที่มีทางออกหนึ่งที่ขาดหายไปไฟล์คีย์ชื่อที่แข็งแกร่ง หากมีหลายโครงการที่จะอ้างอิงโครงการที่ไม่ได้ลงชื่อคุณควรสร้างไฟล์ชื่อคีย์ชื่อใหม่เพื่อหลีกเลี่ยงความขัดแย้งใด ๆ ในกรณีของฉันการแก้ปัญหาไม่ได้สร้างขึ้นและฉันกำลังพยายามแก้ไขเป็นวงกลม ในฐานะของ VS2017 รูปแบบคือ. pfx และไม่ใช่. snk แต่ขั้นตอนเหมือนกัน - คลิกขวาที่โซลูชันและเลือกคุณสมบัติ จากแท็บที่ปรากฏทางด้านซ้ายให้เลือก "การลงชื่อ" คลิกช่องทำเครื่องหมายและเลือกใหม่ ... ระบุชื่อ! และ Voila! มันจะทำ)!
ราชา

59

ฉันค้นหาวิธีแก้ไขปัญหาเดียวกันและยกเลิกตัวเลือก "ลงชื่อการชุมนุม" ไม่ทำงานสำหรับฉัน:

ป้อนคำอธิบายรูปภาพที่นี่

(ตามที่คุณอาจสังเกตเห็นภาพหน้าจอมาจาก VS2010 แต่หวังว่ามันจะช่วยให้ใครบางคน)


ฉันไม่ตรวจสอบการตั้งค่านี้ในโครงการ MVC ของฉัน แต่ก็ยังคงบ่นเกี่ยวกับการอ้างอิงอย่างใดอย่างหนึ่ง มีการตั้งค่าอื่น ๆ สำหรับ MVC หรือไม่
ฮามิด Mayeli

51

ฉันได้เขียนเครื่องมือเพื่อประกอบชุดเครื่องหมายที่มีชื่ออย่างรัดกุมโดยอัตโนมัติรวมถึงที่คุณไม่มีซอร์สโค้ดหรือโครงการที่ถูกทอดทิ้ง มันใช้เทคนิคหลายอย่างที่อธิบายไว้ในคำตอบในวิธีที่ง่ายโดยไม่มีข้อบกพร่องหรือข้อบกพร่องของเครื่องมือที่มีอยู่หรือคำแนะนำวันที่

http://brutaldev.com/post/2013/10/18/NET-Assembly-Strong-Name-Signer

หวังว่านี่จะช่วยให้ทุกคนที่ต้องลงนามในการชุมนุมของบุคคลที่สามโดยไม่ต้องกระโดดผ่านห่วงเพื่อไปที่นั่น


40

คุณสามารถใช้ชุดประกอบที่ไม่ได้ลงชื่อถ้าชุดประกอบของคุณยังไม่ได้ลงนาม


23

การลงนามในการชุมนุมของบุคคลที่สามได้ผลสำหรับฉัน:

http://www.codeproject.com/Tips/341645/Referenced-assembly-does-not-have-a-strong-name

แก้ไข : ฉันได้เรียนรู้ว่ามีประโยชน์ในการโพสต์ขั้นตอนในกรณีที่บทความที่เชื่อมโยงไม่ถูกต้องอีกต่อไป เครดิตทั้งหมดไปที่Hiren Khirsaria :

  1. เรียกใช้พรอมต์คำสั่ง visual studio และไปที่ไดเรกทอรีที่ DLL ของคุณอยู่

    For Example my DLL is located in D:/hiren/Test.dll

  2. ตอนนี้สร้างไฟล์ IL โดยใช้คำสั่งด้านล่าง

    D:/hiren> ildasm /all /out=Test.il Test.dll (คำสั่งนี้สร้างไลบรารีรหัส)

  3. สร้างคีย์ใหม่เพื่อเซ็นชื่อโครงการของคุณ

    D:/hiren> sn -k mykey.snk

  4. ตอนนี้ลงชื่อไลบรารีของคุณโดยใช้ilasmคำสั่ง

    D:/hiren> ilasm /dll /key=mykey.snk Test.il


ลิงก์ของคุณทำให้เคล็ดลับ! ขอบคุณ! และมันอธิบายวิธีการสร้าง mykey.snk (คำตอบอื่น ๆ ไม่ได้พูดว่าอย่างไร)
Nicolas VERHELST

15

วิธีการลงนามแอสเซมบลีของ บริษัท อื่นที่ไม่ได้ลงนาม

  1. เปิดพร้อมรับคำสั่งของนักพัฒนาสำหรับ Visual Studio เครื่องมือนี้มีอยู่ในโปรแกรม Window ของคุณและสามารถพบได้โดยใช้การค้นหา Windows เริ่มต้น
  2. ตรวจสอบให้แน่ใจว่าพรอมต์ของคุณมีการเข้าถึงเครื่องมือต่อไปนี้โดยดำเนินการเพียงครั้งเดียว: sn ildasmและilasm
  3. นำทางไปยังโฟลเดอร์ที่อยู่ Cool.Library.dll ของคุณ
  4. sn –k Cool.Library.snk เพื่อสร้างคู่คีย์ใหม่
  5. ildasm Cool.Library.dll /out:Cool.Library.il เพื่อแยกไลบรารี
  6. move Cool.Library.dll Cool.Library.unsigned.dll เพื่อให้ไลบรารีดั้งเดิมเป็นแบ็คอัพ
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk เพื่อรวมไลบรารีใหม่ด้วยชื่อที่รัดกุม
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"เพื่อรับชื่อที่ผ่านการรับรองโดยสมบูรณ์ คุณจะต้องใช้บิตนี้หากคุณต้องอ้างอิง DLL ในไฟล์กำหนดค่าภายนอกเช่น web.config หรือ app.config

6

ผมมีปัญหานี้สำหรับแอปที่ได้รับการขอชื่อแล้วก็ต้องเปลี่ยนมันเพื่อที่จะอ้างอิงหนึ่งที่ไม่ได้ขอชื่อชุมนุมดังนั้นผมจึงไม่ได้ตรวจสอบ 'เข้าสู่ระบบการชุมนุมในคุณสมบัติของโครงการส่วนการลงนาม แต่มันก็ยังคงบ่น ฉันคิดว่ามันต้องเป็นสิ่งประดิษฐ์ที่ทำให้เกิดปัญหาเพราะฉันทำทุกอย่างถูกต้องและมันก็เป็นเช่นนั้น ฉันพบและลบบรรทัด: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")]] จากไฟล์ assemblyInfo.cs จากนั้นไม่มีการสร้างคำร้องเรียนหลังจากนั้น


ขอบคุณ! เนื่องจากคำตอบของคุณฉันตรวจสอบอีกครั้งสำหรับปัญหาของฉัน (ClosedXML) และพบแพคเกจ nuget ที่ ClosedXML.Signed เช่นกัน
Kiryl

6

ฉันพบปัญหานี้ด้วย ServiceStack dll ที่ฉันติดตั้งด้วย nuget ปรากฎว่ามีอีกชุดของ dll ที่มีป้ายกำกับไว้ ไม่ใช่คำตอบสำหรับทุกคน แต่คุณอาจต้องตรวจสอบชุดประกอบที่มีลายเซ็นของคุณที่มีอยู่แล้วServiceStack.Signed


2

สำหรับฉันปัญหาของฉันคือฉันมีแพคเกจ NuGet เดียวกันสองรุ่นที่ติดตั้งพร้อมกับรุ่นที่แตกต่างกัน


2

การลบเครื่องหมายถูก"ลงนามในชุดประกอบ"ภายใต้แท็บ"การลงนาม"ทำงานเป็น @Michal Stefanow กล่าว

เพิ่มที่นี่เป็นวิธีที่ง่ายที่สุดในการลงชื่อไฟล์ของคุณเองและ / หรือไฟล์ของคนอื่น คุณเพียงแค่ต้องเพิ่มบรรทัดนี้ภายใต้ "บรรทัดคำสั่งเหตุการณ์ post-build":

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\signtool.exe" sign /f "$(ProjectDir)\YourPfxFileNameHere.pfx" /p YourPfxFilePasswordHere /d "Your software title here" /du http://www.yourWebsiteHere.com /t http://timestamp.verisign.com/scripts/timstamp.dll /v "$(BaseOutputPath)$(TargetFileName)"

คุณสามารถลงชื่อไฟล์ของคนอื่นหรือไฟล์ของคุณเองและมากเท่าที่คุณต้องการ

ป้อนคำอธิบายรูปภาพที่นี่


5
นี่คือการลงนามประเภทอื่น สิ่งที่ OP ขอคือวิธีการลงนามแอสเซมบลี. NET ด้วยชื่อที่รัดกุม คุณกำลังแสดงวิธีการลงนามในการปฏิบัติการด้วยใบรับรองการลงนามรหัส สิ่งที่แตกต่าง.
Blue Toque

2

คำถามเก่า แต่ฉันประหลาดใจที่ยังไม่มีใครพูดถึง ilmerge ilmerge มาจาก Microsoft แต่ไม่ได้จัดส่งพร้อม VS หรือ SDK คุณสามารถดาวน์โหลดได้จากที่นี่แม้ว่า นอกจากนี้ยังมีพื้นที่เก็บข้อมูลGitHub คุณยังสามารถติดตั้งจาก nuget:

PM>Install-Package ilmerge

ใช้:

ilmerge assembly.dll /keyfile:key.snk /out:assembly.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug

หากจำเป็นคุณสามารถสร้าง keyfile ของคุณเองโดยใช้ sn (จาก VS):

sn -k key.snk

1
ฉันมีปัญหากับ WireMock.Net ในที่สุดก็ทำให้มันใช้งานได้ แต่ใช้เวลาเล็กน้อยในการหาคำสั่ง PowerShell โดยเฉพาะอย่างยิ่งทั้งกลุ่มของอาร์กิวเมนต์ / lib ในที่สุดก็จะได้รับ ILMerge เพื่อลงนามในการชุมนุม
François

1> Register-PackageSource -ProviderName NuGet -Name NuGet -Location http://www.nuget.org/api/v2
François

2> Install-Package -Name ILMerge
François

3> $env:path += ';C:\Program Files\PackageManagement\NuGet\Packages\ilmerge.2.14.1208\tools'
François

4> ILMerge.exe .\packages\WireMock.Net.1.0.4.2\lib\net452\WireMock.Net.dll /keyfile:key.snk /out:WireMock.Net.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug /lib:.\packages\Newtonsoft.Json.10.0.3\lib\net45\ /lib:.\packages\Handlebars.Net.1.9.0\lib\net40 /lib:.\packages\SimMetrics.Net.1.0.4\lib\net45 /lib:.\packages\Microsoft.Owin.2.0.2\lib\net45 /lib:.\packages\Owin.1.0\lib\net40 /lib:.\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45 /lib:.\packages\MimeKitLite.2.0.1\lib\net45 /lib:.\packages\XPath2.1.0.5.1\lib\net40 /lib:.\packages\RestEase.1.4.4\lib\net45
François

1

สถานการณ์: คุณมีโครงการ A, B, C, D ในโซลูชัน X, Y

โครงการ A, B, C ใน X โครงการ A, C, D ใน Y

ฉันต้องการใช้โครงการ C ในโครงการ A แต่หลังจากนั้นฉันไม่ได้ใช้ ใน bin Debug โครงการ A มี C.dll

ถ้าฉันรวบรวมวิธี X ทั้งหมดดี (ในโซลูชันนี้ฉันลบการอ้างอิง A -> C. ) แต่ในโซลูชัน YI จะได้รับปัญหานี้

วิธีแก้ไขคือลบ C.dll ในโครงการ A bin Debug


0

ขั้นแรกให้แน่ใจว่าแพ็คเกจ nuget ทั้งหมดเป็นรุ่นเดียวกันในทุกโครงการในโซลูชันของคุณ เช่นคุณไม่ต้องการให้โครงการหนึ่งอ้างอิง NLog 4.0.0.0 และโครงการอื่นอ้างอิง NLog 4.1.0.0 จากนั้นลองติดตั้งแพ็กเกจ nuget ใหม่ด้วย

อัพเดต - แพ็คเกจ - ติดตั้งใหม่

ฉันมีชุดประกอบของบุคคลที่ 3 ที่อ้างอิงโดยชุดประกอบของฉัน A และมีเพียง 2 ชิ้นเท่านั้นที่รวมอยู่ในชุดอ้างอิงโดยชุดประกอบ B ของฉันซึ่งอ้างอิงกลุ่ม A

การอ้างอิงที่ขาดหายไปไปยังแอสเซมบลีบุคคลที่สามถูกเพิ่มโดยคำสั่งแพ็คเกจการอัพเดทและข้อผิดพลาดก็หายไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.