111

マルチターゲティング用にVisualStudioビルドをセットアップする方法について少しジレンマがあります。

背景:サードパーティの32ビットDLLへのp /invokingを備えたc#.NET v2.0、セットアッププロジェクトを備えたSQL Compactv3.5SP1。現在、プラットフォームターゲットはx86に設定されているため、Windowsx64で実行できます。

サードパーティの会社がDLLの64ビットバージョンをリリースしたばかりで、専用の64ビットプログラムを作成したいと思います。

これは私がまだ答えを得ていないいくつかの質問を提起します。まったく同じコードベースが欲しい。32ビットのDLLセットまたは64ビットのDLLのいずれかを参照してビルドする必要があります。(サードパーティとSQL Server Compactの両方)

これは、2つの新しい構成セット(Debug64とRelease64)で解決できますか?

2つの別々のセットアッププロジェクト(標準のビジュアルスタジオプロジェクト、Wixやその他のユーティリティなし)を作成する必要がありますか、それとも同じ.msi内で解決できますか?

任意のアイデアや推奨事項を歓迎します。

4

8 に答える 8

83

はい、同じプロジェクト内の同じコードベースでx86とx64の両方をターゲットにすることができます。一般に、VS.NETで適切なソリューション構成を作成すれば問題なく機能します(ただし、完全にアンマネージドDLLへのP / Invokeには、条件付きコードが必要になる可能性があります)。特別な注意が必要な項目は次のとおりです。

  • 同じ名前であるが固有のビット数を持つ外部の管理対象アセンブリへの参照(これはCOM相互運用機能アセンブリにも適用されます)
  • MSIパッケージ(すでに述べたように、x86またはx64のいずれかをターゲットにする必要があります)
  • MSIパッケージ内のカスタム.NETインストーラークラスベースのアクション

アセンブリ参照の問題は、VS.NET内で完全に解決することはできません。これは、指定された名前の参照をプロジェクトに追加できるのは1回だけであるためです。これを回避するには、プロジェクトファイルを手動で編集します(VSでは、ソリューションエクスプローラーでプロジェクトファイルを右クリックし、[プロジェクトのアンロード]を選択してから、もう一度右クリックして[編集]を選択します)。たとえば、アセンブリのx86バージョンへの参照を追加すると、プロジェクトファイルには次のようなものが含まれます。

<Reference Include="Filename, ..., processorArchitecture=x86">
  <HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>

その参照タグを、適用するソリューション構成を示すItemGroupタグ内にラップします。例:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
   <Reference ...>....</Reference>
</ItemGroup>

次に、ItemGroupタグ全体をコピーして貼り付け、64ビットDLLの詳細が含まれるように編集します。例:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
  <Reference Include="Filename, ..., processorArchitecture=AMD64">
     <HintPath>C:\path\to\x64\DLL</HintPath>
   </Reference>
</ItemGroup>

VS.NETでプロジェクトをリロードした後、[アセンブリ参照]ダイアログはこれらの変更によって少し混乱し、間違ったターゲットプロセッサを使用したアセンブリに関する警告が表示される場合がありますが、すべてのビルドは正常に機能します。

次にMSIの問題を解決しますが、残念ながら、これにはVS.NET以外のツール必要になります。関連する基本的なトリック(共通のMSIと32ビットを作成する)を実行するため、その目的にはCaphyonのAdvancedInstallerを使用します。および64ビット固有のMSIであり、.EXEセットアップランチャーを使用して適切なバージョンを抽出し、実行時に必要な修正を実行します)。

他のツールやWindowsインストーラーXML(WiX)ツールセットを使用しても同じ結果が得られる可能性がありますが、高度なインストーラーを使用すると、非常に簡単に(そして非常に手頃な価格で)代替手段を検討したことがありません。

ただし、高度なインストーラーを使用している場合でも、.NETインストーラークラスのカスタムアクションにWiXが必要になる場合があります。特定のプラットフォームでのみ実行する必要がある特定のアクションを指定するのは簡単ですが(それぞれVersionNT64とNOT VersionNT64の実行条件を使用)、組み込みのAIカスタムアクションは、64ビットマシンでも32ビットフレームワークを使用して実行されます。

これは将来のリリースで修正される可能性がありますが、現時点では(または、別のツールを使用して同じ問題のあるMSIを作成する場合)、WiX 3.0のマネージドカスタムアクションサポートを使用して、適切なビット数のアクションDLLを作成できます。対応するフレームワークを使用して実行されます。


編集:バージョン8.1.2以降、AdvancedInstallerは64ビットのカスタムアクションを正しくサポートします。私の最初の答え以来、InstallShieldとその同類と比較した場合、それでも非常に良い値であるにもかかわらず、残念ながら、その価格はかなり上昇しています...


編集:DLLがGACに登録されている場合は、標準の参照タグを次のように使用することもできます(例としてSQLite)。

<ItemGroup Condition="'$(Platform)' == 'x86'">
    <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x64'">
    <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</ItemGroup>

また、条件はすべてのビルドタイプ、リリースまたはデバッグに絞り込まれ、プロセッサアーキテクチャを指定するだけです。

于 2008-09-28T14:06:00.740 に答える
27

両方のプラットフォーム用にビルドされた DLL があり、次の場所にあるとします。

C:\whatever\x86\whatever.dll
C:\whatever\x64\whatever.dll

これから .csproj ファイルを編集するだけです。

<HintPath>C:\whatever\x86\whatever.dll</HintPath>

これに:

<HintPath>C:\whatever\$(Platform)\whatever.dll</HintPath>

これで、両方のプラットフォームを対象とするプロジェクトをビルドできるようになります。MSBuild は、選択したプラットフォームの正しいディレクトリを検索します。

于 2008-09-28T14:43:46.500 に答える
1

あなたの質問に対する完全な答えはわかりませんが、x64 を見ていることを確認して、 SQL Compact 3.5 SP1 ダウンロード ページの追加情報セクションにあるコメントを指摘したいと思います。

SQL Server Compact SP1 の変更と追加の 64 ビット バージョンのサポートにより、SQL Server Compact 3.5 の 32 ビット バージョンと SQL Server Compact 3.5 SP1 の 64 ビット バージョンの中央にインストールされた混合モード環境で、断続的に見えるものが作成される可能性があります。問題。競合の可能性を最小限に抑え、マネージド クライアント アプリケーションのプラットフォームに依存しない展開を可能にするために、Windows インストーラー (MSI) ファイルを使用して 64 ビット バージョンの SQL Server Compact 3.5 SP1 を一元的にインストールするには、32 ビット バージョンの SQL Server もインストールする必要があります。コンパクトな 3.5 SP1 MSI ファイル。ネイティブ 64 ビットのみを必要とするアプリケーションの場合、SQL Server Compact 3.5 SP1 の 64 ビット バージョンのプライベート展開を利用できます。

64 ビット クライアント用に配布する場合、 これを「32 ビット SQLCE ファイルと64 ビット ファイルを含める」と読みます。

人生を面白くすると思います.. 「断続的な問題のように見えるもの」の行が大好きだと言わざるを得ません.

于 2008-09-28T13:20:33.580 に答える
1

x86/x64 依存関係を持つ 1 つの .Net ビルド

他のすべての回答は、プラットフォームに応じて異なるビルドを作成するソリューションを提供しますが、「AnyCPU」構成のみを使用して、x86 および x64 dll で動作するビルドを作成するオプションを提供します。

これには配管コードを書く必要があります。

実行時の正しい x86/x64-dll の解決

手順:

  1. csproj で AnyCPU を使用する
  2. csprojs で x86 または x64 dll のみを参照するかどうかを決定します。選択したアーキテクチャ設定に UnitTests 設定を適応させます。VisualStudio 内でテストをデバッグ/実行するために重要です。
  3. Reference-Properties で、Copy Local & Specific Versionfalseに設定します。
  4. x86/x64 を参照するすべての csproj ファイル の最初のPropertyGroupに次の行を追加して、アーキテクチャの警告を取り除きます。<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
  5. このビルド後のスクリプトをスタートアップ プロジェクトに追加し、このスクリプトのパスを使用および変更して、すべての x86/x64 dll をビルド bin\x86\ bin\x64\ の対応するサブフォルダーにコピーします。

    xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86 xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64

    --> ここでアプリケーションを起動すると、アセンブリが見つからないという例外が発生します。

  6. アプリケーション エントリ ポイントの先頭に AssemblyResolve イベントを登録します。

    AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
    

    この方法で:

    /// <summary>
    /// Event Handler for AppDomain.CurrentDomain.AssemblyResolve
    /// </summary>
    /// <param name="sender">The app domain</param>
    /// <param name="resolveEventArgs">The resolve event args</param>
    /// <returns>The architecture dependent assembly</returns>
    public static Assembly TryResolveArchitectureDependency(object sender, ResolveEventArgs resolveEventArgs)
    {
        var dllName = resolveEventArgs.Name.Substring(0, resolveEventArgs.Name.IndexOf(","));
    
        var anyCpuAssemblyPath = $".\\{dllName}.dll";
    
        var architectureName = System.Environment.Is64BitProcess ? "x64" : "x86";
    
        var assemblyPath = $".\\{architectureName}\\{dllName}.dll";
    
        if (File.Exists(assemblyPath))
        {
            return Assembly.LoadFrom(assemblyPath);
        }
    
        return null;
    }
    
  7. 単体テストがある場合は、AssemblyInitializeAttribute を持つ Method で TestClass を作成し、そこに上記の TryResolveArchitectureDependency-Handler も登録します。(Visual Studio 内で単一のテストを実行すると、これが実行されない場合があります。参照は UnitTest ビンからではなく解決されます。したがって、ステップ 2 の決定は重要です。)

利点:

  • 両方のプラットフォームで 1 つのインストール/ビルド

欠点: - x86/x64 dll が一致しない場合、コンパイル時にエラーが発生しません。- テストは両方のモードで実行する必要があります。

必要に応じて、ビルド後のスクリプトで Corflags.exe を使用して、x64 アーキテクチャ専用の 2 つ目の実行可能ファイルを作成します。

試してみるその他のバリアント: - 開始時に適切な dll がバイナリ フォルダーにコピーされていることを確認する場合は、AssemblyResolve イベント ハンドラーは必要ありません (プロセス アーキテクチャの評価 -> 対応する dll を x64/x86 から bin フォルダーに移動し、元に戻します。 ) - インストーラーでアーキテクチャを評価し、間違ったアーキテクチャのバイナリを削除し、正しいものを bin フォルダーに移動します。

于 2018-08-03T09:57:24.907 に答える
0

MSIインストーラの一部として.NETで記述されたカスタムアクションを使用する場合は、別の問題があります。

これらのカスタムアクションを実行する「shim」は常に32ビットであり、指定したターゲットに関係なく、カスタムアクションも32ビットで実行されます。

詳細と忍者の動き(基本的に、このシムの64ビットバージョンを使用するようにMSIを変更します)

SharePoint64で動作するようにVisualStudio2005/2008でMSIを構築する

VisualStudioを使用した64ビットのマネージドカスタムアクション

于 2008-11-26T15:29:06.760 に答える
0

プロジェクト ファイル内の dll 参照のItemGroupに対して条件を使用できます。
これにより、アクティブな構成を変更するたびに、Visual Studio が条件と参照を再チェックします。
各構成に条件を追加するだけです。

例:

 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <Reference Include="DLLName">
      <HintPath>..\DLLName.dll</HintPath>
    </Reference>
    <ProjectReference Include="..\MyOtherProject.vcxproj">
      <Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project>
      <Name>MyOtherProject</Name>
    </ProjectReference>
  </ItemGroup>
于 2013-09-11T14:23:52.480 に答える
0

2 つのソリューションを異なる方法で生成し、後でマージすることができます。私はVS 2010でこれを行いました。動作します。CMakeによって生成された2つの異なるソリューションがあり、それらをマージしました

于 2012-07-26T23:26:00.797 に答える
0

最後の質問について。ほとんどの場合、単一の MSI 内でこれを解決することはできません。レジストリ/システム フォルダまたは関連するものを使用している場合、MSI 自体がこれを認識する必要があり、32 ビット マシンに適切にインストールするには 64 ビット MSI を準備する必要があります。

製品を 32 ビット アプリケーションとしてインストールし、64 ビット アプリケーションとして実行できる可能性はありますが、それは少し難しいと思います。

そうは言っても、すべてに対して単一のコードベースを保持できるはずだと思います。私の現在の職場では、なんとかそうすることができました。(ただし、すべてを一緒に再生するには、多少のジャグリングが必要でした)

お役に立てれば。32/64 ビットの問題に関連する情報へのリンクを次に示します: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html

于 2008-09-28T13:29:03.140 に答える