web-dev-qa-db-ja.com

NuGetのSystem.Data.SQLite、相互運用DLLが出力ディレクトリにコピーされない

私は 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としてビルドしようとしています。

21
Vimes

展開時にファイルを出力フォルダーから別の場所にコピーしていたので、これが起こっていると思いました。相互運用ファイルがコピーされているという事実を見逃しましたが、それらは出力フォルダー内のx64およびx86フォルダーにコピーされます。

プロジェクトのデバッグでmsbuildを実行する場合、CopySQLiteInteropFilesターゲットへの参照を探して、それが実行されていることを確認できます。

5
Richard

これをプロジェクトファイルにコピーします。

 <PropertyGroup> 
    <ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
    <CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
    <CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
    <CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
 </PropertyGroup>

ソース: SQLite.Interop.dllファイルは、参照プロジェクトで必要な場合、プロジェクト出力パスにコピーされません

11
Stefan

私の場合、問題は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
6
Eternal21

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要素の前にある必要があることに注意してください。

4
florenz

私の場合、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

4
Alessio

私の場合、myProject.csprojファイルにSystem.Data.SQLite.Core.targetsが定義されていませんでした。次の行を追加し、x64x86SQLite.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パッケージが更新されたとき、およびパッケージパスを手動で変更する必要があるかどうかはわかりません。

2
Dave Anderson

追加した

<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パッケージが更新されたときに変更する必要があります。

0
Bart Janson

私の場合、SQLiteのインストールにNuGetを使用していますが、それでも手動でSQliteinterop.dllをリソースとして追加する必要があります。それから私はmuy proyectをビルドし、私が公開するときそれはうまくいきます。 (x86構成での作業)

0
fedeteka

ヌゲットからのSQLiteパッケージを使用するDLLプロジェクトがありますが、そのテストプロジェクトでは常にDLL not found例外が発生します。

私が見つけた最も簡単な解決策は、SQLite nugetパッケージをテストプロジェクトにも追加することでした。

0
Geoff Johnson

上記の答えはどれも私にとってはうまくいかなかったようです。おそらく私は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-宛先ファイルがすでに存在する場合にプロンプ​​トを抑制します。

これをビルドが成功した場合にのみ実行するように設定しました。それが誰かを助けることを願っています。

0
Patrick