Frage

Ich habe ein kleines Dilemma auf, wie mein Visual Studio einzurichten baut für Multi-Targeting.

Hintergrund: c # .NET 2.0 mit p / Aufrufen in 3rd-Party-32-Bit-DLL, SQL Compact v3.5 SP1 mit einem Setup-Projekt. Gerade jetzt ist die Plattform Ziel x86 gesetzt, so kann es auf Windows x64 ausgeführt werden.

Die 3rd-Party-Unternehmen haben gerade 64-Bit-Versionen ihrer DLL und ich mag ein spezielles 64-Bit-Programm erstellen.

Dies wirft einige Fragen, die ich nicht die Antworten auf noch bekommen haben. Ich möchte genau die gleiche Code-Basis haben. Ich muss mit Bezug auf entweder die der 32-Bit-Satz von DLL oder 64-Bit-DLL. (Beide 3rd-Party und SQL Server Compact)

Kann man das mit 2 neuen Sätzen von Konfigurationen (Debug64 und Release64) gelöst werden?

Muss ich erstellen 2 separate Setup-Projekte (std. Visual Studio-Projekte, keine Wix oder andere Dienstprogramm), oder kann dies innerhalb der gleichen .msi gelöst werden?

Alle Ideen und / oder Empfehlungen würden begrüßt werden.

War es hilfreich?

Lösung

Ja, können Sie sowohl die x86 und x64 mit der gleichen Code-Basis im selben Projekt zielen. Arbeit im Allgemeinen, werden die Dinge nur, wenn Sie die richtige Lösung Konfigurationen in VS.NET erstellen (obwohl P / Invoke vollständig unmanaged DLLs wird höchstwahrscheinlich etwas bedingten Code erforderlich): die Elemente, die ich fand besondere Aufmerksamkeit erfordern, sind:

  • Verweise auf außerhalb verwalteten Assemblys mit demselben Namen, aber ihre eigenen spezifischen Bitness (dies gilt auch für COM-Interop Assemblies)
  • Das MSI-Paket (die, wie bereits erwähnt worden ist, müssen entweder x86 oder x64 Ziel)
  • Alle benutzerdefinierten .NET-Installer-Klasse-basierte Aktionen in Ihrem MSI-Paket

Die Referenzausgabebaugruppe kann nicht vollständig innerhalb VS.NET gelöst werden, da es nur erlauben Sie einmal einen Verweis mit einem bestimmten Namen zu einem Projekt hinzuzufügen. Um dies zu umgehen, bearbeiten Sie Ihre Projektdatei manuell (in VS rechten Maustaste auf die Projektdatei im Solution Explorer, wählen Sie Unload-Projekt, dann mit der rechten Maustaste und wählen Sie erneut Bearbeiten). Nach der Zugabe wird eine Referenz auf, sagen wir, die x86-Version einer Assembly, die Projektdatei enthalten so etwas wie:

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

Wickeln Sie den Hinweis-Tag in einem ItemGroup Tag, welche die Lösungskonfiguration es gilt, z:

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

Dann kopieren und den gesamten ItemGroup Tag einfügen und bearbeiten Sie die Details Ihrer 64-Bit-DLL enthalten, z.

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

Nach dem Projekt in VS.NET Nachladen, wird die Versammlung Referenz Dialog ein wenig von diesen Veränderungen verwirrt sein, und Sie können einige Warnungen über Baugruppen mit dem falschen Zielprozessor begegnen, aber alle arbeiten baut gut.

das MSI Problem zu lösen, ist weiter nach oben, und leider wird erfordern ein non-VS.NET Werkzeug: ziehe ich Caphyon des Advanced Installer zu diesem Zweck, wie es zieht den grundlegenden Trick beteiligt (Schaffung einen gemeinsamen MSI, sowie 32-Bit- und 64-Bit-spezifische MSIs, und verwenden sie ein Exe-Setup-Startprogramm aus die richtige Version und machen Sie die erforderlichen Korrekturen zur Laufzeit) sehr, sehr gut zu extrahieren.

Sie können sich wahrscheinlich die gleichen Ergebnisse mit anderen Werkzeugen erreichen oder die Windows Installer XML (WiX) Toolset , aber advanced Installer macht die Dinge so einfach (und ist durchaus erschwinglich zu diesen), die ich habe nie wirklich an Alternativen gesucht.

Eine Sache, die Sie können erfordern WiX noch aber, selbst wenn Advanced Installer verwenden, für Ihre .NET-Installer-Klasse benutzerdefinierte Aktionen ist. Obwohl es trivial bestimmte Aktionen angeben, die nur auf bestimmten Plattformen laufen sollte (die VersionNT64 und NICHT Ausführungsbedingungen VersionNT64 mit jeweils), die sich im internen AI benutzerdefinierte Aktionen wird die 32-Bit-Framework ausgeführt werden, verwenden, auch auf 64-Bit-Maschinen .

Dies kann in einer zukünftigen Version behoben werden, aber jetzt (oder wenn ein anderes Werkzeug mit Ihren MSIs erstellen, die das gleiche Problem hat), können Sie WiX 3.0 der verwalteten benutzerdefinierte Aktion Unterstützung verwenden, um Aktion DLLs mit der erstellen ordnungsgemäße Bitness, die den entsprechenden Rahmen ausgeführt werden, verwendet wird.


Edit: ab Version 8.1.2, Advanced Installer unterstützt korrekt 64-Bit benutzerdefinierte Aktionen. Seit meiner ersten Antwort hat ihr Preis erhöht ziemlich viel, leider, obwohl es, wenn nach wie vor extrem guter Wert ist im Vergleich zu Installshield und seine ilk ...


Edit: Wenn Sie Ihre DLLs im GAC registriert sind, können Sie auch die Standard-Referenz-Tags auf diese Weise (SQLite als Beispiel) verwenden:

<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>

Die Bedingung auch für alle nach unten reduziert bauen Typen, Freigabe oder debuggen und gibt nur die Prozessorarchitektur.

Andere Tipps

Angenommen, Sie haben die DLLs für beide Plattformen zu bauen, und sie sind in der folgenden Position:

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

Sie müssen lediglich Ihre CSPROJ Datei von dieser bearbeiten:

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

Um dies zu:

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

Sie sollten dann in der Lage sein, Ihr Projekt zu bauen beide Plattformen Targeting und MSBuild in das richtige Verzeichnis für die gewählte Plattform aussehen wird.

die gesamten Antwort auf Ihre Frage nicht sicher - aber dachte, dass ich in der Zusatzinformation Abschnitt der SQL Compact 3.5 SP1-Download-Seite sehen Sie bei x64 suchen -. hoffe, es hilft

  

Aufgrund von Änderungen in SQL Server Compact   SP1 und zusätzliche 64-Bit-Version   Unterstützung, zentral installiert und gemischt   Modus Umgebungen von 32-Bit-Version von   SQL Server Compact 3.5 und 64-Bit   Version von SQL Server Compact 3.5 SP1   kann schaffen, was zu sein scheint   weise Probleme. Zur Minimierung der   Potenzial für Konflikte und zu ermöglichen   Plattform neutral Bereitstellung verwalteter   Client-Anwendungen, zentral   Installation der 64-Bit-Version von SQL   Server Compact 3.5 SP1 die Verwendung von   Windows Installer (MSI-Datei) auch   erfordert die 32-Bit-Version installieren   von SQL Server Compact 3.5 SP1 MSI   Datei. Für Anwendungen, die nur   erfordern native 64-bit, privat   Einsatz der 64-Bit-Version von   SQL Server Compact 3.5 SP1 kann sein   genutzt werden.

Ich las dies als „gehören die 32-Bit-SQLCE Dateien sowie die 64-Bit-Dateien“, wenn die Verteilung für 64-Bit-Clients.

Das macht das Leben interessant denke ich .. muss sagen, dass ich die Liebe Linie „was zeitweise Probleme zu sein scheint“ ... klingt ein bisschen wie „Sie stellen sich vor, Dinge, aber nur für den Fall, dies zu tun ...“

In Bezug auf Ihre letzte Frage. Wahrscheinlich können nicht Sie dies in einem einzigen MSI lösen. Wenn Sie mit Registry / System-Ordner oder irgendetwas im Zusammenhang, sich das MSI sich dessen bewusst sein muss, und Sie müssen eine 64-Bit-MSI vorbereiten, um richtig auf 32-Bit-Computer installiert werden.

Es gibt eine Möglichkeit, dass Sie können Sie Produkt als 32 es Anwendung installiert machen und noch in der Lage sein, um es als 64-Bit laufen zu lassen, aber ich denke, dass etwas schwer zu erreichen sein kann.

, dass gesagt wird ich denke, sollten Sie in der Lage sein, eine einzige Code-Basis für alles, was zu halten. In meinem aktuellen Arbeitsplatz wir haben es geschafft, dies zu tun. (Aber es hat einige Jonglieren nahm, um alles zusammen spielen zu machen)

Hoffe, das hilft. Heres ein Link zu einem paar Informationen zu 32/64 Bit Fragen im Zusammenhang: http: //blog.typemock. com / 2008/07 / Registrierungs-on-windows-64-Bit-Doppel your.html

Wenn Sie in .NET als Teil Ihrer MSI-Installer geschrieben benutzerdefinierte Aktionen verwenden, dann haben Sie ein anderes Problem.

Die ‚Shim‘, dass diese benutzerdefinierten Aktionen läuft immer dann Aktion Ihrer benutzerdefinierte 32bit wird 32bit läuft auch, trotz allem, was Ziel, das Sie angeben.

Weitere Informationen und einige ninja bewegt zu umgehen (im Grunde das MSI ändern, um die 64-Bit-Version dieses Shim zu verwenden)

ein MSI in Visual Studio 2005/2008 Aufbauend auf einer Sharepoint zu arbeiten 64

64-Bit-verwaltete benutzerdefinierte Aktionen mit Visual Studio

Sie können zwei Lösungen anders erzeugen und kombinieren sich danach! Ich tat dies für VS 2010 und es funktioniert. Ich hatte zwei verschiedene Lösungen, die durch CMake und ich fusionierte sie

Sie können eine Bedingung ein verwenden ItemGroup für die DLL-Referenzen in der Projektdatei.
Das wird Visual Studio verursacht den Zustand und die Referenzen noch einmal zu überprüfen, wenn Sie die aktive Konfiguration ändern.
Fügen Sie einfach eine Bedingung für jede Konfiguration.

Beispiel:

 <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>

Ein mit x86 / x64-Abhängigkeiten bauen .NET

Während alle anderen Antworten, die Sie geben, eine Lösung anders machen Builds nach der Plattform, gebe ich Ihnen eine Option, um nur die „AnyCPU“ Konfiguration haben und einen Build machen, die mit Ihrem x86 und x64-DLLs funktioniert.

Sie haben einige Sanitär-Code für diese zu schreiben. Ich konnte nicht diese Arbeit mit app.config bekommen. Wenn jemand anders einen Weg kennt es über app.config zu lösen Ich möchte wirklich wissen.

Auflösung des korrekten x86 / x64-DLLs zur Laufzeit

Schritte:

  1. Verwenden Sie AnyCPU in csproj
  2. Entscheiden Sie, ob Sie nur die x86 oder x64 die DLLs in Ihrem csprojs verweisen. Passen Sie die Unittests Einstellungen auf die Architektur von Ihnen gewählten Einstellungen. Es ist wichtig für das Debugging / Laufen die Tests innerhalb Visual Studio.
  3. Eine Referenz-Eigenschaften eingestellt Lokal kopieren & Spezielle Version false
  4. Sie sich von der Architektur Warnungen befreien, indem Sie die Zeile in die erste Seite Property in alle Ihre csproj Dateien, in denen Sie x86 / x64 Referenz: <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
  5. Fügen Sie diese postbuild Skript zu Ihrem Startprojekt, die Nutzung und die Pfade dieses Skript sp modifizieren, dass es kopiert alle Ihre x86 / x64-DLLs in Unterordner Ihres Build bin \ x86 \ bin entsprechenden \ x64 \

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

    -> Wenn Sie Anwendung jetzt beginnen würde, eine Ausnahme erhalten dass die Baugruppe konnte nicht gefunden werden.

  6. Registrieren Sie das AssemblyResolve Ereignis gleich zu Beginn Ihrer Anwendung Einstiegspunkt

    AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
    

    withthis Methode:

    /// <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. Wenn Sie Unit-Tests haben eine Testclass mit einer Methode machen, die einen AssemblyInitializeAttribute hat und auch die oben TryResolveArchitectureDependency-Handler dort registrieren. (Dies wird manchmal nicht ausgeführt werden, wenn Sie einzelne Tests in Visual Studio ausführen, werden die Referenzen nicht aus dem Unittest ist gelöst werden. Deshalb ist die Entscheidung in Schritt 2 ist wichtig.)

Vorteile:

  • Eine Installation / Bauen für beide Plattformen

Nachteile:  - Keine Fehler bei der Kompilierung, wenn x86 / x64-DLLs nicht übereinstimmen.  - Sie sollten sich trotzdem Test in beiden Modi laufen

Geben Sie optional eine zweite ausführbare Datei erstellen, die für die x64-Architektur mit Corflags.exe in postbuild Skript exklusiv

Weitere Varianten ausprobieren:  - Sie würden die AssemblyResolve Event-Handler nicht benötigen, wenn Sie sonst versichern, dass die DLLs in Ihrem Binär-Ordner beim Start kopiert werden (Prozessarchitektur auswerten. -> Umzug dlls von x64 / x86 zu Binärordner entspricht und zurück)  -. In Installer Architektur bewerten und Binärdateien für falsche Architektur löschen und die richtigen zu dem Mülleimer-Ordner verschieben

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top