2008-09-28 26 views
103

Tengo un pequeño dilema sobre cómo configurar mis compilaciones de Visual Studio para múltiples destinatarios.Orientación a 32 bits y a 64 bits con Visual Studio en la misma solución/proyecto

Antecedentes: C# .NET v2.0 con p/invocación a archivos DLL de 32 bits de terceros, SQL compacto v3.5 SP1, con un proyecto de instalación. En este momento, el objetivo de la plataforma está configurado en x86, por lo que se puede ejecutar en Windows x64.

La empresa de terceros acaba de lanzar versiones de 64 bits de sus DLL y quiero crear un programa dedicado de 64 bits.

Esto plantea algunas preguntas que aún no tengo las respuestas. Quiero tener exactamente la misma base de código. Debo compilar con referencias al conjunto de 32 bits de DLL o DLL de 64 bits. (Ambos de terceros y SQL Server Compact)

¿Se puede resolver esto con 2 nuevos conjuntos de configuraciones (Debug64 y Release64)?

¿Debo crear 2 proyectos de configuración separados (proyectos estándar de Visual Studio, sin Wix o cualquier otra utilidad), o se puede resolver dentro del mismo .msi?

Cualquier idea y/o recomendación sería bienvenida.

+0

@Magnus Johansson: se pueden utilizar dos configuraciones para lograr la mitad de su meta. El MSI es un poco más difícil. – user7116

Respuesta

80

Sí, puede orientar tanto x86 y x64 con la misma base de código en el mismo proyecto. En general, las cosas solo funcionarán si crea las configuraciones de solución correctas en VS.NET (aunque P/Invoke a DLL totalmente no administradas probablemente requerirá algún código condicional): los elementos que encuentro que requieren atención especial son:

  • las referencias a los ensamblados administrados fuera con el mismo nombre pero su propio valor de bits específica (esto también se aplica a los ensamblados de interoperabilidad COM)
  • el paquete MSI (que, como ya se ha señalado, tendrá que dirigirse a x86 o x64)
  • Cualquier instalador .NET personalizado Acciones basadas en clase en su paquete MSI

El problema de referencia de ensamblaje no se puede resolver completamente en VS.NET, ya que solo le permitirá agregar una referencia con un nombre dado a un proyecto una vez. Para evitar esto, edite su archivo de proyecto manualmente (en VS, haga clic con el botón derecho en su archivo de proyecto en el Explorador de soluciones, seleccione Descargar proyecto, luego haga clic con el botón secundario y seleccione Editar). Después de añadir una referencia a, por ejemplo, la versión x86 de un montaje, el archivo de proyecto contendrá algo como:

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

Wrap que hacen referencia a la etiqueta dentro de una etiqueta ItemGroup que indica la configuración de la solución que se aplica, por ejemplo:

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

a continuación, copiar y pegar la etiqueta completa ItemGroup, y editarla para contener los detalles de su DLL de 64 bits, por ejemplo:

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

Después de cargar de nuevo el proje ct en VS.NET, el cuadro de diálogo Referencia de ensamblado se verá un poco confundido por estos cambios, y es posible que encuentre algunas advertencias sobre ensamblajes con el procesador de destino incorrecto, pero todas sus compilaciones funcionarán correctamente.

Resolver el problema de MSI es el siguiente, y por desgracia este se requerir una herramienta non-VS.NET: Prefiero Caphyon de Advanced Installer para tal fin, ya que se quita el truco básico implicado (crear un MSI común, así como los MSI específicos de 32 y 64 bits, y usan un iniciador de instalación .EXE para extraer la versión correcta y realizar las correcciones necesarias en el tiempo de ejecución) muy, muy bien.

Probablemente pueda lograr los mismos resultados usando otras herramientas o el Windows Installer XML (WiX) toolset, pero el Instalador avanzado hace las cosas tan fáciles (y es bastante asequible) que nunca he visto alternativas.

Una cosa es que puede seguir requiriendo WiX aunque, incluso cuando se usa Advanced Installer, es para sus acciones personalizadas de la clase de instalador .NET.Aunque es trivial especificar ciertas acciones que solo deberían ejecutarse en ciertas plataformas (utilizando las condiciones de ejecución VersionNT64 y NO VersionNT64, respectivamente), las acciones personalizadas de AI incorporadas se ejecutarán utilizando el Framework de 32 bits, incluso en máquinas de 64 bits. .

Esto se puede arreglar en una versión futura, pero por ahora (o cuando usa una herramienta diferente para crear sus MSI que tienen el mismo problema), puede usar el soporte de acción personalizado administrado de WiX 3.0 para crear archivos DLL de acción la bitness adecuada que se ejecutará utilizando el Marco correspondiente.


Editar: a partir de la versión 8.1.2, el instalador avanzado admite correctamente las acciones personalizadas de 64 bits. Desde mi respuesta original, su precio ha aumentado un poco, por desgracia, a pesar de que sigue siendo un valor muy bueno en comparación con InstallShield y su calaña ...


Editar: Si sus DLL se registran en la GAC, también puede utilizar las etiquetas estándar de referencia de esta manera (SQLite como ejemplo):

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

la condición también se reduce a construir todo tipo, liberación o de depuración, y simplemente especifica la arquitectura del procesador.

+0

En Visual Studio 2008, encontré que s no se podían anidar. Esta solución funcionó bien una vez que hice el nuevo s por debajo del grupo el resto de los s. También tuve que cambiar x86 a AnyCPU, que probablemente se relaciona con la historia de mi proyecto en particular. –

+0

Ese Instalador avanzado se ve bastante impresionante. – Pat

+0

Esto puede ser una pregunta tonta, pero ¿cómo llegar al archivo para editarlo manualmente? – hrh

1

No estoy seguro de la respuesta total a su pregunta, pero pensé que señalaría un comentario en la sección Información adicional del SQL Compact 3.5 SP1 download page viendo que está viendo x64 - espero que ayude.

Debido a cambios en SQL Server Compact SP1 y el apoyo adicional de 64 bits versión , instalados centralmente y mixtos entornos de modo de la versión de 32 bits de SQL Server Compact 3.5 y 64-bit versión de SQL Server Compact 3.5 SP1 puede crear lo que parecen ser problemas intermitentes. Para minimizar el potencial de conflictos, y para permitir plataforma de despliegue neutro de aplicaciones administradas cliente, centralmente instalar la versión de 64 bits de SQL Server Compact 3.5 SP1 mediante el archivo de Windows Installer (MSI) también requiere la instalación de la Versión de 32 bits del archivo SQL Server Compact 3.5 SP1 MSI . Para aplicaciones que solo requieren 64-bit privado, despliegue privado de de la versión de 64 bits de SQL Server Compact 3.5 SP1 puede ser utilizado.

leí esto como "incluir los archivos de 32 bits SQLCE así como los archivos de 64 bits" si la distribución para los clientes de 64 bits.

Hace la vida más interesante, supongo ... debo decir que me encanta la línea "lo que parece ser un problema intermitente" ... suena un poco como "estás imaginando cosas, pero por las dudas, haz esto ..."

0

En relación con su última pregunta. Lo más probable es que no puedas resolver esto dentro de un solo MSI. Si está utilizando carpetas de registro/sistema o algo relacionado, el propio MSI debe ser consciente de esto y debe preparar un MSI de 64 bits para instalarlo correctamente en una máquina de 32 bits.

Existe la posibilidad de que pueda hacer que su producto se instale como una aplicación 32 it y aún así pueda hacer que funcione como 64 bit one, pero creo que puede ser algo difícil de lograr.

Dicho esto, creo que debería poder mantener una única base de código para todo. En mi lugar de trabajo actual lo hemos logrado. (pero tomó algunos malabares hacer que todo juegue junto)

Espero que esto ayude. Heres un enlace a alguna información relacionada con temas de 32/64 bits: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html

26

Digamos que usted tiene las DLL construyen para ambas plataformas, y se encuentran en la siguiente ubicación:

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

sólo hay que editar el archivo .csproj de esto:

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

Para esto:

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

Debería poder construir su proyecto orientado a ambas plataformas, y MSB uild buscará en el directorio correcto para la plataforma elegida.

+0

Esto sería genial si funciona, pero no es así. Al menos no para mí –

+10

No se supone que es: C: \ whatever \ $ (Platform) \ whatever.dll Andreas

+1

esto funcionó milagros para mí, gracias un paquete! –

0

Si usa Acciones personalizadas escritas en .NET como parte de su instalador MSI, entonces tiene otro problema.

El 'shim' que ejecuta estas acciones personalizadas es siempre de 32 bits, luego su acción personalizada también se ejecutará a 32 bits, a pesar del objetivo que especifique.

Más información & algunos movimientos ninja a moverse (básicamente cambiar el MSI a utilizar la versión de 64 bits de este suplemento)

Building an MSI in Visual Studio 2005/2008 to work on a SharePoint 64

64-bit Managed Custom Actions with Visual Studio

0

Se pueden generar dos soluciones de manera diferente y fusionar ellos después! Hice esto para VS 2010. Y funciona. Tuve 2 soluciones diferentes generadas por CMake y las fusioné

0

Puede usar una condición en un ItemGroup para las referencias dll en el archivo de proyecto.
Esto hará que visual studio vuelva a verificar la condición y las referencias siempre que cambie la configuración activa.
Simplemente agregue una condición para cada configuración.

Ejemplo:

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