Sí, puede apuntar a x86 y x64 con la misma base de código en el mismo proyecto. En general, las cosas simplemente funcionarán si crea las configuraciones de solución correctas en VS.NET (aunque P / Invoke a DLL completamente no administradas probablemente requerirá algún código condicional): los elementos que encontré que requieren atención especial son:
- Referencias a ensamblados administrados externos con el mismo nombre pero con su propio bitness específico (esto también se aplica a ensamblados de interoperabilidad COM)
- El paquete MSI (que, como ya se ha señalado, deberá apuntar a x86 o x64)
- Cualquier acción personalizada basada en la clase del instalador de .NET en su paquete MSI
El problema de la referencia de ensamblado no se puede resolver por completo dentro de VS.NET, ya que solo le permitirá agregar una referencia con un nombre dado a un proyecto una vez. Para solucionar esto, edite su archivo de proyecto manualmente (en VS, haga clic con el botón derecho en el archivo de su proyecto en el Explorador de soluciones, seleccione Descargar proyecto, luego haga clic con el botón derecho nuevamente y seleccione Editar). Después de agregar una referencia a, digamos, la versión x86 de un ensamblado, su archivo de proyecto contendrá algo como:
<Reference Include="Filename, ..., processorArchitecture=x86">
<HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>
Envuelva esa etiqueta de referencia dentro de una etiqueta ItemGroup que indique la configuración de la solución a la que se aplica, por ejemplo:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<Reference ...>....</Reference>
</ItemGroup>
Luego, copie y pegue la etiqueta ItemGroup completa y edítela para que contenga 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 volver a cargar su proyecto en VS.NET, el cuadro de diálogo Referencia de ensamblado estará 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 bien.
Resolver el problema de MSI es el siguiente, y lamentablemente esto se requiere 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 de 32 bits y MSI específicos de 64 bits, y use un iniciador de configuración .EXE para extraer la versión correcta y hacer las reparaciones necesarias en tiempo de ejecución) muy, muy bien.
Probablemente pueda lograr los mismos resultados utilizando otras herramientas o el conjunto de herramientas Windows Installer XML (WiX) , pero Advanced Installer hace las cosas tan fáciles (y es bastante asequible) que nunca he buscado alternativas.
Sin embargo, una cosa para la que aún puede necesitar WiX, incluso cuando usa el Instalador avanzado, es para las acciones personalizadas de la Clase de instalador .NET. Aunque es trivial especificar ciertas acciones que solo deberían ejecutarse en ciertas plataformas (usando las condiciones de ejecución VersionNT64 y NO VersionNT64, respectivamente), las acciones personalizadas de IA incorporadas se ejecutarán usando el Framework de 32 bits, incluso en máquinas de 64 bits .
Esto puede corregirse en una versión futura, pero por ahora (o cuando use una herramienta diferente para crear sus MSI que tenga el mismo problema), puede usar el soporte de acciones personalizadas administradas de WiX 3.0 para crear archivos DLL de acción con el bitness adecuado que se ejecutará utilizando el Framework correspondiente.
Editar: a partir de la versión 8.1.2, Advanced Installer admite correctamente acciones personalizadas de 64 bits. Desde mi respuesta original, su precio ha aumentado bastante, desafortunadamente, aunque sigue siendo un valor extremadamente bueno en comparación con InstallShield y sus similares ...
Editar: si sus DLL están registradas en el GAC, también puede usar las etiquetas de referencia estándar 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 todos los tipos de compilación, lanzamiento o depuración, y solo especifica la arquitectura del procesador.