Saya mencoba membuat paket NuGet untuk .Net assembly yang melakukan pinvoke ke win32 dll. Saya perlu mengemas baik rakitan dan dll asli dengan rakitan ditambahkan ke referensi proyek (tidak ada masalah pada bagian ini) dan dll asli harus disalin ke direktori keluaran proyek atau beberapa direktori relatif lainnya.
Pertanyaan saya adalah:
- Bagaimana saya mengemas dll asli tanpa studio visual mencoba menambahkannya ke dalam daftar referensi?
- Apakah saya harus menulis install.ps1 untuk menyalin dll asli? Jika demikian, bagaimana saya dapat mengakses konten paket untuk menyalinnya?
nuget
nuget-package
nuget-spec
AlonFStackoverflow
sumber
sumber
Jawaban:
Menggunakan
Copy
target dalam file target untuk menyalin pustaka yang diperlukan tidak akan menyalin file-file itu ke proyek lain yang mereferensikan proyek, menghasilkan aDllNotFoundException
. Ini dapat dilakukan dengan file target yang lebih sederhana, menggunakanNone
elemen, karena MSBuild akan menyalin semuaNone
file ke proyek referensi.Tambahkan file target ke
build
direktori paket nuget bersama dengan pustaka asli yang diperlukan. File target akan mencakup semuadll
file di semua direktori anak daribuild
direktori. Jadi untuk menambahkanx86
danx64
versi pustaka asli yang digunakan olehAny CPU
rakitan terkelola Anda akan berakhir dengan struktur direktori yang mirip dengan berikut:Direktori yang sama
x86
danx64
akan dibuat di direktori output proyek ketika dibangun. Jika Anda tidak memerlukan subdirektori maka file**
dan%(RecursiveDir)
dapat dihapus dan sebaliknya sertakan file yang diperlukan dalambuild
direktori secara langsung. File konten lain yang diperlukan juga dapat ditambahkan dengan cara yang sama.File yang ditambahkan seperti
None
dalam file target tidak akan ditampilkan dalam proyek ketika dibuka di Visual Studio. Jika Anda bertanya-tanya mengapa saya tidak menggunakanContent
folder di nupkg itu karena tidak ada cara untuk mengaturCopyToOutputDirectory
elemen tanpa menggunakan skrip PowerShell (yang hanya akan dijalankan di dalam Visual Studio, bukan dari command prompt, pada build server atau di IDE lain, dan tidak didukung dalam proyek DNX project.json / xproj ) dan saya lebih suka menggunakan aLink
ke file daripada memiliki salinan tambahan file dalam proyek.Pembaruan: Meskipun ini juga harus bekerja dengan
Content
daripadaNone
tampaknya ada bug di msbuild sehingga file tidak akan disalin ke proyek referensi lebih dari satu langkah dihapus (misalnya proj1 -> proj2 -> proj3, proj3 tidak akan mendapatkan file dari paket NuGet proj1 tetapi proj2 akan).sumber
'$(MSBuildThisFileDirectory)' != '' And HasTrailingSlash('$(MSBuildThisFileDirectory)')
diperlukan? Saya pikir ituMSBuildThisFileDirectory
selalu diatur. Kapan itu tidak terjadi?**\*.dll
? Itu menyalin semua.dll
file di semua direktori. Anda dapat dengan mudah melakukannya**\*.*
untuk menyalin seluruh pohon direktori.Saya baru-baru ini memiliki masalah yang sama ketika saya mencoba untuk membangun paket EmguCV NuGet termasuk rakitan terkelola dan lirari bersama yang tidak dikelola (yang juga harus ditempatkan dalam
x86
subdirektori) yang harus disalin secara otomatis ke direktori output build setelah setiap build .Inilah solusi yang saya buat, yang hanya mengandalkan NuGet dan MSBuild:
Tempatkan rakitan terkelola di
/lib
direktori paket (bagian yang jelas) dan pustaka bersama yang tidak dikelola serta file terkait (mis. Paket .pdb) di/build
subdirektori (seperti yang dijelaskan dalam dokumen NuGet ).Ganti nama semua
*.dll
ujung file yang tidak dikelola menjadi sesuatu yang berbeda, misalnya*.dl_
untuk mencegah NuGet mengeluh tentang dugaan rakitan yang ditempatkan di tempat yang salah ( "Masalah: Rakitan folder di luar lib." ).Tambahkan
<PackageName>.targets
file khusus di/build
subdirektori dengan sesuatu seperti konten berikut (lihat keterangan di bawah):File di atas
.targets
akan disuntikkan pada instalasi paket NuGet dalam file proyek target dan bertanggung jawab untuk menyalin pustaka asli ke direktori output.<AvailableItemName Include="NativeBinary" />
menambahkan item baru "Build Action" untuk proyek (yang juga tersedia di dropdown "Build Action" di dalam Visual Studio).<NativeBinary Include="...
menambahkan pustaka asli yang ditempatkan di/build/x86
proyek saat ini dan membuatnya dapat diakses oleh target kustom yang menyalin file-file itu ke direktori output.<TargetPath>x86</TargetPath>
menambahkan custom metadata ke file dan memberi tahu target kustom untuk menyalin file asli kex86
subdirektori dari direktori output aktual.The
<PrepareForRunDependsOn ...
blok menambahkan target kustom ke daftar target membangun tergantung pada, lihat Microsoft.Common.targets file untuk rincian.Target kustom
CopyNativeBinaries
,, berisi dua tugas salin. Yang pertama bertanggung jawab untuk menyalin*.dl_
file apa pun ke direktori output sambil mengubah ekstensi mereka kembali ke aslinya*.dll
. Yang kedua hanya menyalin sisanya (misalnya*.pdb
file apa saja ) ke lokasi yang sama. Ini dapat diganti dengan satu tugas salin dan skrip install.ps1 yang harus mengganti nama semua*.dl_
file*.dll
selama instalasi paket.Namun, solusi ini masih tidak akan menyalin binari asli ke direktori keluaran proyek lain yang merujuk pada yang awalnya termasuk paket NuGet. Anda masih harus merujuk paket NuGet di proyek "final" Anda juga.
sumber
DllNotFoundException
dibuang.<NoWarn>NU5100</NoWarn>
ke file proyek AndaBerikut adalah alternatif yang menggunakan
.targets
untuk menyuntikkan DLL asli di proyek dengan properti berikut.Build action
=None
Copy to Output Directory
=Copy if newer
Manfaat utama dari teknik ini adalah bahwa DLL asli disalin ke
bin/
folder proyek tergantung secara transitif.Lihat tata letak
.nuspec
file:Ini
.targets
file tersebut:Ini memasukkan
MyNativeLib.dll
seolah-olah itu adalah bagian dari proyek asli (tapi anehnya file tersebut tidak terlihat di Visual Studio).Perhatikan
<Link>
elemen yang menetapkan nama file tujuan dibin/
folder.sumber
Content
keNone
?Jika ada orang lain yang tersandung di ini.
Nama
.targets
file HARUS sama dengan ID Paket NuGetApa pun tidak akan berhasil.
Kredit pergi ke: https://sushihangover.github.io/nuget-and-msbuild-targets/
Saya harus membaca lebih teliti seperti yang sebenarnya dicatat di sini. Butuh waktu lama bagi saya ..
sumber
Agak terlambat tapi saya sudah membuat paket nuget untuk itu.
Idenya adalah untuk memiliki folder khusus tambahan dalam paket nuget Anda. Saya yakin Anda sudah tahu Lib dan Konten. Paket nuget yang saya buat mencari Folder bernama Output dan akan menyalin semua yang ada di sana ke folder keluaran proyek.
Satu-satunya hal yang harus Anda lakukan adalah menambahkan ketergantungan nuget ke paket http://www.nuget.org/packages/Baseclass.Contrib.Nuget.Output/
Saya sudah menulis posting blog tentang hal itu: http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=6&mobile=0
sumber
Ada solusi C # murni yang saya temukan agak mudah digunakan dan saya tidak perlu repot dengan keterbatasan NuGet. Ikuti langkah ini:
Sertakan pustaka asli di proyek Anda dan setel properti Build Action-nya ke
Embedded Resource
.Rekatkan kode berikut ke dalam kelas tempat Anda PInvoke perpustakaan ini.
Panggil metode ini dari konstruktor statis seperti berikut ini
UnpackNativeLibrary("win32");
dan itu akan membongkar pustaka ke disk tepat sebelum Anda membutuhkannya. Tentu saja, Anda perlu memastikan bahwa Anda memiliki izin menulis ke bagian disk tersebut.sumber
Ini adalah pertanyaan lama, tetapi saya memiliki masalah yang sama sekarang, dan saya menemukan perubahan haluan yang sedikit rumit tetapi sangat sederhana dan efektif: buat di folder Konten standar Nuget struktur berikut dengan satu subfolder untuk setiap konfigurasi:
Saat Anda mengemas file nuspec, Anda akan menerima pesan berikut untuk setiap pustaka asli di folder Debug dan Rilis:
Kami tidak memerlukan "solusi" seperti itu karena ini hanya tujuan kami: bahwa perpustakaan asli tidak ditambahkan sebagai rujukan NET Assemblies.
Keuntungannya adalah:
Kerugiannya adalah:
sumber
Saya tidak bisa menyelesaikan masalah Anda, tetapi saya bisa memberikan saran.
Persyaratan utama Anda adalah: "Dan jangan mendaftar secara otomatis referensi" .....
Jadi, Anda harus terbiasa dengan "item solusi"
Lihat referensi di sini:
Menambahkan item tingkat solusi dalam paket NuGet
Anda harus menulis beberapa voodoo PowerShell untuk mendapatkan salinan dll asli Anda ke dalam rumahnya (sekali lagi, karena Anda TIDAK ingin voodoo auto-add-referensi menyala)
Ini adalah file ps1 yang saya tulis ..... untuk meletakkan file di folder referensi pihak ketiga.
Ada cukup banyak di sana bagi Anda untuk mengetahui cara menyalin dll asli Anda ke beberapa "rumah" ... tanpa harus mulai dari awal.
Sekali lagi, ini bukan serangan langsung, tetapi lebih baik daripada tidak sama sekali.
sumber
Masukkan itu adalah folder konten
perintah
nuget pack [projfile].csproj
akan melakukannya untuk Anda secara otomatis jika Anda akan menandai file sebagai konten.kemudian edit file proyek seperti yang disebutkan di sini menambahkan elemen ItemGroup & NativeLibs & None
bekerja untukku
sumber