私は System.Data.SQLite Core(x86/x64)from NuGet をインストールしました。警告なしでビルドされましたが、System.DllNotFoundException
に関してSQLite.Interop.dll
をスローしました。私は自分のプロジェクトを不正操作して、SQLite.Interop.dll
をNuGetパッケージのディレクトリの下から出力ディレクトリにコピーしたところ、例外なく実行されるようになりました。
NuGetパッケージが適切な相互運用機能DLLを出力ディレクトリに配置するようにプロジェクトを構成しなかったのはなぜですか?それができるはずです。
私は相互運用の初心者で、以前はパスでSystem.Data.SQLite.dll
を直接参照していたこのコードベースを継承しました。プロジェクトのプロセッサアーキテクチャとSystem.Data.SQLite
の不一致に関する警告を取り除くために、NuGetに切り替えました。すべてのプロジェクトをAnyCPUとしてビルドしようとしています。
展開時にファイルを出力フォルダーから別の場所にコピーしていたので、これが起こっていると思いました。相互運用ファイルがコピーされているという事実を見逃しましたが、それらは出力フォルダー内のx64およびx86フォルダーにコピーされます。
プロジェクトのデバッグでmsbuildを実行する場合、CopySQLiteInteropFiles
ターゲットへの参照を探して、それが実行されていることを確認できます。
これをプロジェクトファイルにコピーします。
<PropertyGroup>
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
<CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
<CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
<CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>
ソース: SQLite.Interop.dllファイルは、参照プロジェクトで必要な場合、プロジェクト出力パスにコピーされません
私の場合、問題はSQLiteをクラスライブラリプロジェクト内で使用していて、別のWPF(guiタイプ)プロジェクトで使用されていたということでした。
SQL.Interop.dllが出力ディレクトリにコピーされない問題を解決するには、プロジェクトのプロパティ->ビルドイベント内で次のビルド後コマンドを使用します。
xcopy "$(SolutionDir)packages\System.Data.SQLite.Core.1.0.101.0\build\net451\x86\SQLite.Interop.dll" "$(OutputDir)" /y /f
/y overwrites
/f displays actual filenames being copied
System.Data.SQLite.Core
NuGetパッケージバージョン1.0.104では、@ Eternal21および@Patrickと同じ問題が発生しました。つまり、プロジェクトAはSQLiteを参照し、プロジェクトBはAを参照し、SQlite.Interop.dll
はBの出力ディレクトリにコピーされません。
BではなくプロジェクトAの問題を解決するソリューションを見つけました。これは、Aを参照する将来のすべてのプロジェクトの問題を一度修正するため、より堅牢なソリューションです。NuGetパッケージの.targets
ファイルには、次のセクションが含まれています。
<ItemGroup Condition="'$(ContentSQLiteInteropFiles)' != '' And
'$(ContentSQLiteInteropFiles)' != 'false' And
'@(SQLiteInteropFiles)' != ''">
<Content Include="@(SQLiteInteropFiles)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
このセクションでは、SQLite.Interop.dll
を参照として追加します。この参照は、プロジェクトAの出力と、参照プロジェクト(Bなど)の出力にコピーする必要があります。ただし、MSBuildプロパティContentSQLiteInteropFiles
は、デフォルトでは未定義です(理由はわかりません)。最初の条件で参照を無効にします。これを有効にするために、プロジェクトAの.csproj
ファイルのPropertyGroup
要素に次の行を追加しました。
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
この行は、NuGetパッケージの.targets
ファイルのImport
要素の前にある必要があることに注意してください。
私の場合、SQL.Interop.dllはNugetによってコピーされなかったため、適切なバージョンのdllを手動でx86およびx64フォルダーに配置して問題を解決しました。
NugetからSqliteをインストールした場合、SQL.Interop.dllはこのフォルダーにあります(.NET 4.0の場合)
PROJECT_FOLDER\packages\System.Data.SQLite.Core.1.0.*.*\build\net40
私の場合、myProject.csproj
ファイルにSystem.Data.SQLite.Core.targets
が定義されていませんでした。次の行を追加し、x64
のx86
とSQLite.Interop.dll
の両方のバージョンがすべてのビルドターゲットにコピーされるようになりました。
<Import Project="..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.98.1\build\net45\System.Data.SQLite.Core.targets')" />
System.Data.SQLite.Core
のNuGetパッケージが更新されたとき、およびパッケージパスを手動で変更する必要があるかどうかはわかりません。
追加した
<PropertyGroup>
<ContentSQLiteInteropFiles>false</ContentSQLiteInteropFiles>
<CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
<CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
<CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>
Nugetパッケージを参照するプロジェクトのcsproj内。この部分は、「System.Data.SQLite.Core.targets」の「インポート」の上にある必要があります。
次に、csproj-fileに以下を追加して、「SQLite.Interop.dll」のx64バージョンをbinフォルダーに配置します。
<ItemGroup>
<Content Include="..\packages\System.Data.SQLite.Core.1.0.111.0\build\net46\x64\SQLite.Interop.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
このステートメントは、nugetパッケージが更新されたときに変更する必要があります。
私の場合、SQLiteのインストールにNuGetを使用していますが、それでも手動でSQliteinterop.dllをリソースとして追加する必要があります。それから私はmuy proyectをビルドし、私が公開するときそれはうまくいきます。 (x86構成での作業)
ヌゲットからのSQLiteパッケージを使用するDLLプロジェクトがありますが、そのテストプロジェクトでは常にDLL not found例外が発生します。
私が見つけた最も簡単な解決策は、SQLite nugetパッケージをテストプロジェクトにも追加することでした。
上記の答えはどれも私にとってはうまくいかなかったようです。おそらく私はVS2015を使用しているためですが、それがこの問題に独自のソリューションを追加する正当な理由として私を襲いました。
私の特定の状況は@ Eternal21と同じです-nugetを介してSQLiteが追加されたクライアントライブラリを使用するWPF UIがあります。そして、はい、問題はInterop.dllがスタートアップアプリケーション(つまり、SQLiteがインストールされていないWPF UI)にコピーされなかったことです。
急いでいる場合は、nugetを使用してSQLiteをWPFプロジェクトに追加するだけの解決策がすばやく簡単に修正できます。
私のやや強引なソリューションはXCOPYを使用しますが、x86とx64の両方のディレクトリをコピーするという利点があり、デバッグおよびリリースビルドにも対応します。その欠点は、ハードコードされたプロジェクト名が含まれていることです。マクロを使用して最初のマクロを削除する方法はわかりますが、2番目のマクロを削除する方法を簡単に確認できなかったため、プロジェクト名が変更された場合は手動で変更する必要があります(ただし、これはかなりまれです) )。
私の解決策は、スタートアッププロジェクトのビルド後にこれらのXCOPYコマンドを使用することです。
xcopy $(SolutionDir)DALProject\bin\$(ConfigurationName)\x64\SQLite.Interop.dll $(SolutionDir)WPFProject\bin\$(ConfigurationName)\x64\*.* /C /F /S /E /Y
xcopy $(SolutionDir)DALProject\bin\$(ConfigurationName)\x86\SQLite.Interop.dll $(SolutionDir)WPFProject\bin\$(ConfigurationName)\x86\*.* /C /F /S /E /Y
/ C-エラーが発生してもコピーを続行します(おそらくこれは必要ありません)。
/ F-コピーされるファイルの完全パスを表示します(ビルド出力をクリーンアップするために省略できる場合があります)。
/ S-サブディレクトリをコピーします(これは、/ x86および/ x64フォルダーを作成するための唯一の方法でした)。
/ E-ディレクトリとサブディレクトリをコピーします(/ Sが重複している可能性があります)。
/ Y-宛先ファイルがすでに存在する場合にプロンプトを抑制します。
これをビルドが成功した場合にのみ実行するように設定しました。それが誰かを助けることを願っています。