2016-10-18 22 views
10

Điều này khiến tôi phát điên trong vài tháng và tôi vẫn không thể đạt được nó. Các thư viện được quản lý của tôi được trích xuất từ ​​gói Nuget nhưng không được trích xuất từ ​​các thư viện gốc.Tự động quản lý các tệp DLL gốc và được quản lý từ Gói Nuget

Chúng tôi có một loạt các thư viện được quản lý và bản địa do một công ty khác cung cấp. Chúng tôi có cả hai phiên bản x86x64. Để sử dụng chúng trong một dự án ASP.NET Core, tôi phải tạo một gói Nuget.

kiến ​​trúc của tôi là:

  • một lớp thư viện ASP.NET cốt lõi mà tôi thay đổi để nhắm mục tiêu .NET Framework đầy đủ mà thôi. Dự án này tham chiếu NuGet Package
  • một trang web ASP.NET Lõi của tôi cũng nhắm mục tiêu .NET Framework đầy đủ và tham khảo thư viện lớp

Tất nhiên, cuối cùng, tôi cần các thư viện mẹ đẻ của tôi được chiết xuất để thời gian chạy đúng thư mục của trang web (ví dụ: \bin\Debug\net461\win7-x64).

Đối với thời điểm giải pháp của tôi là:

  • để đưa libs có nguồn gốc bên trong thư mục build
  • tạo một file targets đó sao chép chúng vào các $(OutputPath) (mà thậm chí còn không phải là thư mục runtime)
  • thêm một số lệnh MsBuild vào xproj của trang web của tôi để nhận tệp mục tiêu trong thư mục $(USERPROFILE)\.nuget\packages\ của tôi và thực thi nó
  • bằng tay các file DLL có nguồn gốc tại chiết xuất trong bin thư mục vào runtime một

Tôi đã cố gắng để sao chép chúng trực tiếp vào thư mục runtime sử dụng một số cấu hình trong project.json (Thực sự tôi không nhớ tất cả những điều tôi đã cố gắng cho phần này) nhưng điều này luôn luôn thất bại. Ngoài ra mặc dù tôi đã chỉ định SkipUnchangedFiles="true" trong tệp mục tiêu của mình, điều này chỉ bị bỏ qua và các tệp DLL của tôi được sao chép vào thư mục bin của tôi trong mỗi lần tạo.

Đây là một quá trình nặng chỉ để đạt được một giải nén DLL, bây giờ tôi thực sự muốn loại bỏ tất cả những gì MsBuild và nhận được một giải pháp đơn giản hơn nhiều.

Tôi biết với các phiên bản mới hơn của Nuget, bây giờ nó có khả năng giải nén chúng một cách tự nhiên mà không cần trợ giúp thêm các lệnh MsBuild tùy chỉnh. Theo văn bản here, dự án C# thậm chí không cần một tập tin targets

Tiếp theo, C++ và JavaScript dự án mà có thể tiêu thụ gói NuGet bạn cần một tập tin .targets để xác định lắp ráp cần thiết và các tập tin winmd. (C# và các dự án Visual Basic tự động làm điều này.)

Tôi đã mở một tab trong trình duyệt của mình trong một vài tháng (original link) và nhận ra tài nguyên này gần đây đã bị xóa khỏi trang web Nuget. Nó đã giải thích cách sử dụng thư mục runtimes để tự động trích xuất các tệp DLL gốc. Tuy nhiên tôi chưa bao giờ có thể có được một kết quả thành công như nó đã được giải thích.Bây giờ trang này đã bị xóa và thay thế bằng this one với rất ít giải thích và không nói về thư mục này runtimes.

Tôi đoán là tôi nên sử dụng thư mục runtimes cho các tệp DLL gốc và lib để quản lý nhưng tôi không chắc chắn 100% về điều đó. (Tôi cũng nên sử dụng thư mục build?)

Tôi đã thử một số việc (tôi không thể nhớ lại số lần thử, như tôi đã nói vài tháng đau đầu ...) như this architecture (Tôi không hiểu tại đây điểm của việc có build/native là những gì và cũng thổ dân thư mục dưới runtimes) enter image description here

tôi cũng đã cố gắng để sử dụng cấu trúc phiên bản .NET framework như mô tả here cho các thư viện quản lý của tôi.

This có vẻ là cũng là một phần của giải pháp

Kiến trúc bị bỏ qua bởi trình biên dịch khi tạo một tài liệu tham khảo lắp ráp. Đó là một khái niệm thời gian tải. Trình tải sẽ thích tham chiếu cụ thể về kiến ​​trúc nếu nó tồn tại.

Một thủ thuật bạn có thể sử dụng để sản xuất lắp ráp AnyCPU là sử dụng corflags để loại bỏ kiến ​​trúc khỏi cụm x86 của bạn. EG: corflags/32BITREQ- MySDK.dll. Corflags là một phần của .NET SDK và có thể tìm thấy trong dấu nhắc lệnh của nhà phát triển VS.

Đó là những gì tôi đã làm, chuyển đổi cả x86 và x64 DLL để AnyCPU (không biết nếu nó làm điều gì đó cho x64 DLL nhưng tôi đã không nhận lỗi) và sau đó cố gắng kiến ​​trúc khác nhau trong gói NuGet của tôi, nhưng vẫn không làm việc.

Thời gian chạy mặc định mà không cần bất kỳ mục trong project.json là win7-x64, vì vậy tôi đã quyết định để xác định một cách rõ ràng chỉ trong trường hợp

"runtimes": { 
    "win7-x64": {} 
}, 

Vì vậy, đây là Runtime Định danh Tôi đang sử dụng cho tất cả những nỗ lực của tôi trong tôi Gói Nuget. Tuy nhiên tôi không quan tâm đến phiên bản windows. Tôi thực sự muốn có win-x86 hoặc giành chiến thắng-x64 nhưng nó có vẻ là một giá trị không hợp lệ theo this page

của Windows RIDs

Windows 7/Windows Server 2008 R2

  • win7- x64
  • win7-x86

Windows 8/Windows server 2012

  • win8-x64
  • win8-x86
  • win8-cánh tay

Windows 8.1/Windows Server 2012 R2

  • win81-x64
  • win81-x86
  • win81-cánh tay

Windows 10/Windows Server 2016

  • win10-x64
  • win10-x86
  • win10- tay
  • win10-arm64

Tuy nhiên Github source này được mô tả RID nhiều hơn như vậy mà nguồn là đúng?

Như bạn có thể thấy, có rất nhiều điều bí ẩn ở đây, chủ yếu là do thiếu tài liệu hoặc thậm chí mâu thuẫn giữa các tài liệu khác nhau.

Nếu ít nhất tôi có thể có một ví dụ làm việc, thì tôi có thể thực hiện các bài kiểm tra của mình để trả lời các câu hỏi khác như cố gắng chung win-x64 RID hoặc xem tôi có thể bao gồm libs được quản lý của mình bất kể phiên bản .NET Framework không.

Hãy chú ý đến bối cảnh đặc biệt của tôi: Tôi có một mục tiêu đầy đủ .NET Framework

Cám ơn câu trả lời của bạn dự án ASP.NET Core, tôi tuyệt vọng để làm việc điều đơn giản này.

+0

Bạn có phải sử dụng Gói NuGet không? Tôi không nghĩ rằng bạn nhất thiết phải sử dụng chúng vì đó là dự án ASP.NET Core. Tôi khá chắc chắn bạn có thể Thêm tài liệu tham khảo> Duyệt và chọn một DLL? – SimonGates

+0

Không, tôi không thể thêm tham chiếu đến DLL gốc trực tiếp, tôi ** phải tạo một gói. Vì vậy, tôi muốn đóng gói tất cả (bản địa và quản lý) trong một gói Nuget duy nhất. –

+0

Có thể xem vấn đề này ở đây github.com/aspnet/dnx/issues/402#issuecomment-151040736 Dường như đã có cách thêm vào để tải nó trong RC1 – Tseng

Trả lời

5

Tôi sẽ cố gắng giải thích tất cả nỗi đau và giải pháp mà tôi đã trải qua càng chi tiết càng tốt. Trong ví dụ của tôi, tôi sử dụng các tệp văn bản đơn giản AAA86.txt, AAA64.txtAAAany.txt thay vì các tệp DLL gốc để chỉ đơn giản là minh họa quy trình trích xuất.

Điều đầu tiên bạn cần phải biết: Nếu bạn cố gắng pha trộn kiến ​​trúc native NuGet với một thư mục lib chứa một số thư viện quản lý, nó sẽ không hoạt

enter image description here

Trong trường hợp đó DLL được quản lý của bạn sẽ được sao chép vào thư mục đầu ra của dự án của bạn nhưng KHÔNG sao chép thư mục gốc của bạn.

Nhờ Jon Skeet, người đã chỉ cho tôi theo hướng tốt, khuyên tôi hãy xem Grpc.Core package. Bí quyết là tạo ra một tập tin targets sẽ xử lý việc khai thác DLL.

enter image description here

tập tin mục tiêu của bạn nên chứa một cái gì đó như thế này

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemGroup Condition=" '$(Platform)' == 'x64' "> 
     <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\AAA64.txt"> 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
      <Link>AAA64.txt</Link> 
     </Content> 
    </ItemGroup> 

    <ItemGroup Condition=" '$(Platform)' == 'x86' OR '$(Platform)' == 'AnyCPU' "> 
     <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\native\AAA86.txt"> 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
      <Link>AAA86.txt</Link> 
     </Content> 
    </ItemGroup> 

</Project> 

Bây giờ vài điều khác mà bạn cần biết:

1) Visual Studio không quan tâm tại tất cả về cài đặt bạn chọn, nó sẽ luôn sử dụng RID giả. (Trong trường hợp của tôi, tôi luôn luôn kết thúc với một thư mục win7-x64 mặc dù tôi trên Windows 10 ...)

enter image description here

2) Các platform setting trong project.json của bạn cũng là hoàn toàn vô dụng

{ 
    "buildOptions": { 
     "platform": "x64" 
    } 
} 

3) Trong runtimes settings nếu bạn thiết lập chỉ win và/hoặc win-x64

"runtimes": { 
    "win": {}, 
    "win-x64": {} 
} 

Visual Studio thay vào đó sẽ sử dụng win7-x64. Nhưng nếu bạn thêm win10-x64 trong khi bạn đang ở trên một máy tính Windows 10 thì điều này sẽ được sử dụng

4) Nếu bạn biên dịch ứng dụng của bạn với một generic RID như thế này

dotnet build -c debug -r win 

Sau đó, tập tin targets bạn sẽ nhận được kiến trúc máy của bạn (x64 trong trường hợp của tôi) thay vì AnyCPU như tôi đã mong đợi

5) Nếu bạn chỉ có thư viện gốc mà không được quản lý thì việc trích xuất sẽ rk mà không có một tập tin mục tiêu nếu bạn làm theo các kiến ​​trúc runtimes/RID/native

6) Với CHỈ thư viện có nguồn gốc trong gói của tôi, choosen RID sẽ luôn luôn được win-x64 xây dựng với Visual Studio như tôi đã nói với bạn vào thư mục runtime luôn tạo là win7-x64, bất kể cấu hình tôi chọn là gì. Nếu tôi chỉ có một duy nhất win RID trong gói của tôi thì nó sẽ được chọn thành công.

Các vấn đề liên quan