Saya baru mengenal konfigurasi proyek di Visual Studio 2010, tetapi saya telah melakukan beberapa penelitian dan masih belum dapat memecahkan masalah ini. Saya punya solusi Visual Studio dengan C ++ DLL referensi C # DLL. C # DLL referensi beberapa DLL lainnya, beberapa di dalam proyek saya dan beberapa eksternal. Ketika saya mencoba untuk mengkompilasi C ++ DLL, saya mendapatkan peringatan ini:
peringatan MSB3270: Ada ketidaksesuaian antara arsitektur prosesor proyek yang sedang membangun "MSIL" dan arsitektur prosesor dari referensi "[internal C # dll]", "x86".
Ini memberitahu saya untuk pergi ke Pengelola Konfigurasi untuk menyelaraskan arsitektur saya. C # DLL diatur dengan target platform x86. Jika saya mencoba mengubah ini ke sesuatu yang lain, seperti CPU Apa pun, itu mengeluh karena salah satu DLL eksternal itu tergantung pada platform target x86.
Ketika saya melihat Manajer Konfigurasi itu menunjukkan Platform untuk C # DLL saya sebagai x86 dan untuk proyek C ++ saya sebagai Win32. Ini sepertinya pengaturan yang tepat; tentunya saya tidak ingin proyek untuk proyek C ++ saya memiliki platform diatur ke x64, yang merupakan satu-satunya pilihan lain yang disajikan.
Apa yang saya lakukan salah di sini?
sumber
Jawaban:
Peringatan ini tampaknya telah diperkenalkan dengan Visual Studio 11 Beta dan .NET 4.5 baru, meskipun saya kira itu mungkin terjadi sebelumnya.
Pertama, ini hanyalah peringatan. Seharusnya tidak ada salahnya jika Anda hanya berurusan dengan dependensi x86. Microsoft hanya mencoba memperingatkan Anda ketika Anda menyatakan bahwa proyek Anda kompatibel dengan "CPU apa pun" tetapi Anda memiliki ketergantungan pada proyek atau .dll perakitan yang baik x86 atau x64. Karena Anda memiliki ketergantungan x86, maka secara teknis proyek Anda tidak kompatibel dengan "Any CPU". Untuk membuat peringatan hilang, Anda harus benar-benar mengubah proyek Anda dari "CPU apa pun" menjadi "x86". Ini sangat mudah dilakukan, berikut adalah langkah-langkahnya.
<New..>
Ini akan membuat peringatan hilang dan juga menyatakan bahwa perakitan atau proyek Anda sekarang tidak lagi "Any CPU" yang kompatibel tetapi sekarang spesifik x86. Ini juga berlaku jika Anda membangun proyek 64 bit yang memiliki ketergantungan x64; Anda hanya akan memilih x64 saja.
Satu catatan lain, proyek dapat kompatibel dengan "Apa saja CPU" biasanya jika mereka murni proyek .NET. Masalah ini hanya muncul jika Anda memperkenalkan ketergantungan (dll pihak ke-3 atau proyek yang dikelola C ++ Anda sendiri) yang menargetkan arsitektur prosesor tertentu.
sumber
Ini adalah peringatan yang sangat keras kepala dan sementara itu peringatan yang sah ada beberapa kasus di mana itu tidak dapat diselesaikan karena penggunaan komponen pihak ketiga dan alasan lainnya. Saya memiliki masalah yang sama kecuali bahwa peringatan itu karena platform proyek saya adalah AnyCPU dan saya merujuk perpustakaan MS yang dibangun untuk AMD64. Ini ada dalam Visual Studio 2010, dan tampaknya diperkenalkan dengan menginstal VS2012 dan .Net 4.5.
Karena saya tidak dapat mengubah perpustakaan MS yang saya rujuk, dan karena saya tahu bahwa lingkungan penyebaran target saya hanya 64-bit, saya dapat dengan aman mengabaikan masalah ini.
Bagaimana dengan peringatan itu? Microsoft memposting sebagai respons terhadap laporan Connect bahwa satu opsi adalah untuk menonaktifkan peringatan itu. Anda hanya harus melakukan ini karena Anda sangat menyadari arsitektur solusi Anda dan Anda sepenuhnya memahami target penyebaran Anda dan tahu bahwa itu bukan masalah di luar lingkungan pengembangan.
Anda dapat mengedit file proyek Anda dan menambahkan grup properti ini dan pengaturan untuk menonaktifkan peringatan:
sumber
Aturan praktis yang baik adalah "buka DLL, EXE tertutup", yaitu:
Ketika Anda membangun EXE sebagai AnyCPU, semua yang Anda lakukan adalah menunda keputusan tentang apa proses bitness yang akan digunakan untuk OS, yang akan JIT EXE sesuai dengan keinginannya. Yaitu, OS x64 akan membuat proses 64-bit, OS x86 akan membuat proses 32-bit.
Membangun DLL sebagai AnyCPU membuatnya kompatibel untuk proses mana pun.
Untuk lebih lanjut tentang seluk-beluk memuat perakitan, lihat di sini . Ringkasan eksekutif berbunyi seperti:
sumber
Yang merupakan jenis masalah, DLL tidak benar-benar bisa memilih bagaimana bitness dari prosesnya. Itu sepenuhnya ditentukan oleh proyek EXE, itulah perakitan pertama yang dimuat sehingga pengaturan target Platformnya adalah yang menghitung dan menetapkan bitness untuk proses tersebut.
DLL tidak punya pilihan, mereka harus kompatibel dengan bitness proses. Jika tidak, maka Anda akan mendapatkan Kaboom besar dengan BadImageFormatException ketika kode Anda mencoba menggunakannya.
Jadi pilihan yang baik untuk DLL adalah AnyCPU sehingga mereka bekerja dengan baik. Itu merek banyak akal bagi C # DLL, mereka melakukan pekerjaan baik cara. Tapi tentu saja, bukan DLL mode campuran C ++ / CLI Anda, ini berisi kode yang tidak dikelola yang hanya dapat berfungsi dengan baik ketika proses berjalan dalam mode 32-bit. Anda bisa mendapatkan sistem build untuk menghasilkan peringatan tentang itu. Itulah tepatnya yang Anda dapatkan. Hanya peringatan, itu masih dibangun dengan benar.
Punt masalah saja. Tetapkan target Platform proyek EXE ke x86, itu tidak akan berfungsi dengan pengaturan lainnya. Dan simpan semua proyek DLL di AnyCPU.
sumber
Saya mendapatkan peringatan yang sama dengan yang saya lakukan ini:
tambahkan tag berikut:
Muat ulang proyek
sumber
Saya memiliki masalah ini hari ini dan hanya melihat konfigurasi bangunan di Visual Studio tidak membantu karena menunjukkan CPU untuk proyek yang tidak membangun dan proyek yang dirujuk.
Saya kemudian mencari di csproj dari proyek referensi dan menemukan ini:
Entah bagaimana PlatformTarget ini ditambahkan di tengah perubahan konfigurasi dan IDE sepertinya tidak melihatnya.
Menghapus baris ini dari proyek yang dirujuk menyelesaikan masalah saya.
sumber
Jika C # DLL Anda memiliki dependensi berbasis x86, maka DLL Anda sendiri harus x86. Saya tidak benar-benar melihat jalan keluarnya. VS mengeluh tentang mengubahnya menjadi (misalnya) x64 karena eksekusi 64-bit tidak dapat memuat pustaka 32-bit.
Saya agak bingung tentang konfigurasi proyek C ++. Pesan peringatan yang disediakan untuk build menunjukkan bahwa itu ditargetkan untuk AnyCPU, karena melaporkan platform yang ditargetkan adalah [MSIL], tetapi Anda mengindikasikan bahwa konfigurasi untuk proyek tersebut sebenarnya adalah Win32. Aplikasi Win32 asli tidak boleh melibatkan MSIL - meskipun mungkin perlu memiliki dukungan CLR diaktifkan jika sedang berinteraksi dengan perpustakaan C #. Jadi saya pikir ada beberapa celah di sisi informasi.
Bisakah saya dengan hormat meminta Anda meninjau dan memposting sedikit lebih detail dari konfigurasi yang tepat dari proyek dan bagaimana mereka saling terkait? Dengan senang hati membantu lebih lanjut jika memungkinkan.
sumber
Selain David Sacks jawaban, Anda juga mungkin perlu untuk pergi ke
Build
tabProject Properties
dan setPlatform Target
untukx86
untuk proyek yang memberikan Anda peringatan ini. Meskipun Anda mungkin mengharapkannya, pengaturan ini tampaknya tidak disinkronkan dengan pengaturan di manajer konfigurasi.sumber
Untuk proyek C #, target x86 melakukan seperti apa rasanya. Dikatakan bahwa perakitan ini hanya mendukung arsitektur x86. Demikian juga untuk x64. CPU di sisi lain mengatakan bahwa saya tidak peduli arsitektur mana, saya mendukung keduanya. Jadi, 2 pertanyaan berikutnya adalah (1) apa konfigurasi dari executable yang menggunakan dll ini? dan (2) apa itu bitnessOS / Komputer Anda? Alasan saya bertanya adalah karena jika executable Anda dikompilasi untuk berjalan dalam 64-bit, maka ia MEMBUTUHKAN semua dependensi untuk dapat berjalan dalam mode 64-bit juga. Unit CPU apa pun Anda harus dapat dimuat, tetapi mungkin referensi beberapa ketergantungan lain yang hanya mampu berjalan dalam konfigurasi x86. Periksa semua dependensi dan dependensi-of-dependensi untuk memastikan semuanya "CPU apa pun" atau "x64" jika Anda berencana untuk menjalankan executable dalam mode 64-bit. Kalau tidak, Anda akan memiliki masalah.
Dalam banyak hal, Visual Studio tidak membuat kompilasi campuran dari CPU Apa pun dan berbagai rakitan bergantung arsitektur mudah. Itu bisa dilakukan, tetapi sering kali mengharuskan bahwa sebuah rakitan yang seharusnya "Setiap CPU" harus dikompilasi secara terpisah untuk x86 dan x64 karena beberapa dependensi-of-a-dependensi di suatu tempat memiliki dua versi.
sumber
Saya pernah mengalami masalah yang sama sebelumnya, khususnya ketika menambahkan solusi pengujian ke solusi x64 yang ada, seperti SharePoint. Dalam kasus saya, ini sepertinya ada hubungannya dengan fakta bahwa templat proyek tertentu ditambahkan sebagai platform tertentu secara default.
Inilah solusi yang sering berhasil bagi saya: atur semuanya ke platform yang benar di Configuration Manager (konfigurasi drop-down yang aktif, kata Debug secara normal, adalah cara yang baik untuk sampai ke sana) dan platform proyek (di properti proyek), kemudian bangun, lalu atur semuanya kembali ke AnyCPU. Kadang-kadang saya harus menghapus dan menambahkan kembali beberapa dependensi (DLL di setiap proyek properti) dan kadang-kadang "Jalankan tes dalam proses 32 bit atau 64 bit" (klik dua kali pengaturan Local.tests dan pergi ke Host) harus diubah.
Sepertinya saya hanya mengatur sesuatu kemudian mengembalikannya, tetapi mungkin ada lebih banyak yang terjadi di balik layar yang tidak saya lihat. Ini bekerja cukup konsisten untuk saya di masa lalu.
sumber
Untuk proyek saya, saya memiliki persyaratan untuk dapat membangun x86 dan x64. Masalah dengan ini adalah bahwa setiap kali Anda menambahkan referensi saat menggunakan satu, maka itu mengeluh ketika Anda membangun yang lain.
Solusi saya adalah mengedit file * .csproj secara manual sehingga baris-baris seperti ini:
diubah menjadi ini:
sumber
Saya punya masalah serupa itu disebabkan oleh MS UNIT Test DLL. Aplikasi WPF saya dikompilasi sebagai x86 tetapi unit DLL uji (direferensikan file EXE) sebagai "Any CPU". Saya mengubah unit test DLL untuk dikompilasi untuk x86 (sama seperti EXE) dan telah di-resov.
sumber
Anda juga bisa mendapatkan peringatan ini untuk majelis MS Fakes yang tidak mudah untuk diselesaikan karena f.csproj dibangun berdasarkan perintah. Untungnya , Fakes xml memungkinkan Anda menambahkannya di sana .
sumber
Harus ada cara untuk membuat .NET EXE / DLL AnyCPU, dan setiap DLL yang tidak dikelola tergantung pada kompilasi keduanya dengan x86 dan x64, keduanya dibundel mungkin dengan nama file yang berbeda dan kemudian .NET module secara dinamis memuat yang benar berdasarkan pada saat runtime arsitektur prosesor. Itu akan membuat AnyCPU kuat. Jika C ++ DLL hanya mendukung x86 atau x64 maka AnyCPU tentu saja tidak ada gunanya. Tetapi ide kedua bundling yang belum saya lihat diimplementasikan karena manajer konfigurasi bahkan tidak menyediakan sarana untuk membangun proyek yang sama dua kali dengan konfigurasi / platform berbeda untuk beberapa bundling yang memungkinkan AnyCPU atau bahkan konsep lain seperti konfigurasi apa pun dimungkinkan.
sumber
Saya memiliki peringatan yang sangat mirip dalam bangunan saya. Proyek saya ditetapkan untuk menargetkan .NET 4.5, pada server build, Windows 8.1 SDK (untuk .NET 4.5.1) diinstal. Setelah memperbarui proyek saya untuk menargetkan .NET 4.5.1 (bukan masalah bagi saya, adalah untuk aplikasi yang benar-benar baru), saya tidak menerima peringatan lagi ...
sumber
Saya memecahkan peringatan ini dengan mengubah "Configuration Manager" menjadi Release (Mixed Plataform).
sumber
Saya mendapat peringatan ini di Visual Studio 2012 ketika menyusun tugas skrip pipa SSIS SQL Server 2012 SP1 - sampai saya menginstal SQL Server 2012 SP2.
sumber
Saya memiliki masalah yang sama dengan koneksi pembukaan SQLite, dan menggunakan Nuget dan menginstal komponen yang digunakan dalam proyek (SQLite) memperbaikinya! coba pasang komponen Anda dengan cara ini dan periksa hasilnya
sumber
Gunakan https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-example :
sumber