visual tutorial studio que pudo predeterminado manifiestos los firmar crear chrome certificado .net clickonce manifest

.net - tutorial - ClickOnce: el archivo ya existe. ¿Por qué un archivo DLL intenta copiarse dos veces con ClickOnce?



firmar los manifiestos de clickonce (4)

Consolide sus paquetes nuget, si tiene 2 referencias que dependen de diferentes versiones de un tercer paquete nuget, a veces puede tener 2 referencias a un mismo paquete nuget. Esto hará que Clickonce falle.

¿ClickOnce solo mira el archivo de manifiesto de la aplicación para determinar qué archivos dll copiar en la máquina del cliente o también interroga las partes internas de un ensamblaje para determinar los archivos de dependencia?

La razón por la que pregunto es porque obtengo el siguiente error de ClickOnce al intentar iniciar una aplicación WPF .NET 4 que se publicó con ClickOnce: el archivo C:/Users/CNelson/AppData/Local/Temp/Deployment/PGX6P33A.35N/AJQL8AC8.D60/tx16_rtf.dll ya existe.

Este error comenzó después de haber incluido una referencia a dos dlls .NET de terceros que hacen referencia a un archivo dll no administrado (tx16_rtf.dll). Quiero que se copie tx16_rtf.dll a la carpeta bin en la PC del cliente, así que lo incluí en mi proyecto y configuré la Acción de compilación en ''Contenido'' y la Copia al directorio de salida en ''Copiar siempre''.

Sin embargo, por algún motivo, cuando intento iniciar la aplicación, ClickOnce intenta copiar el archivo ''tx16_rtf.dll'' dos veces, lo que genera un error.

Si observo el archivo de manifiesto de implementación, puedo ver claramente una y solo una entrada para el archivo ''tx16_rtf.dll''. Entonces, mi pregunta es, ¿por qué ClickOnce intenta copiar el archivo ''tx16_rtf.dll'' dos veces si solo existe una vez en el archivo de manifiesto de implementación?

A continuación se muestra un fragmento del archivo de manifiesto de implementación que hace referencia a ''tx16_rtf.dll'':

<file name="tx16_rtf.dll" size="839680"> <hash> <dsig:Transforms> <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" /> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <dsig:DigestValue>V6i2QcARl3+1SJHCugoazb9zrOY=</dsig:DigestValue> </hash> </file>


En su solución de Visual Studio, ¿cómo se agrega el archivo? Por favor intenta lo siguiente.

Agrega la dll a tu proyecto.

Si tiene una referencia a la dll en Referencias, establezca las propiedades en la dll de esta manera: Acción de compilación = ninguna, Copiar en el directorio de salida = "no copiar". Luego elimine la referencia y luego vuelva a agregarla, pero apunte a esa dll en su carpeta de proyecto local. En la referencia, establezca "copiar local" en verdadero.

Si no tiene una referencia para la dll, establezca las propiedades en la dll de esta manera: Build Action = "copy". Copiar en el directorio de salida = "Copiar siempre".

Si tiene una referencia, desea que la razón para incluirla se base en la referencia y no en las propiedades de dll. Si no tiene una referencia, desea configurar la dll específicamente para ser incluida.

También verifique el cuadro de diálogo Archivos de la aplicación y asegúrese de que la dll no esté marcada como Incluir (requisito previo), sino que incluya o incluya (requerido).


Esto también puede suceder si a veces hace referencia a .csproj y a veces a compilar .dll

P.ej:

Main.csproj: ref A.csproj ref B.csproj A.csproj ref B.dll


No menciona si está utilizando el maravilloso ( tos ) MAGE.EXE para generar su manifiesto de implementación. Sin embargo, he encontrado el mismo error ''El archivo x ya existe'', y es causado por ensamblajes administrados que llaman a funciones en ensamblajes nativos a través de P / Invoke.

Para cada ensamblaje administrado en la ubicación especificada por el argumento -FromDirectory para MAGE.EXE, MAGE creará un conjunto de elementos <dependency><dependentAssembly>...</dependentAssembly></dependency> (incluida la base de código del ensamblado, identidad, tamaño, hash, etc). Para cada otro archivo (incluidos los ensamblados nativos no administrados) MAGE.EXE creará un elemento <file>...</file> .

Sin embargo, en el momento de la instalación, parece que ClickOnce realmente inspecciona los metadatos de manifiesto de cada ensamblaje administrado. Entonces, si su aplicación tiene ManagedAssemblyA que P / Invoca código en NativeAssemblyB (o tx16_rtf.dll en su caso), verá a través de ILDASM que el manifiesto para ManagedAssemblyA tiene una declaración .module extern NativeAssemblyB.dll .

Solo puedo suponer que ClickOnce, mientras procesa el elemento <dependentAssembly codebase="ManagedAssemblyA.dll"> , inspecciona los metadatos del ensamblaje, ve que hay un ensamblado nativo referenciado, ve que también se encuentra en la misma ubicación de implementación y lo copia. . Luego, cuando luego se procesa el elemento <file name="NativeAssemblyB.dll"> , se <file name="NativeAssemblyB.dll"> un error, ya que ya ha copiado este archivo y se supone que no instalarlo es el curso de acción más seguro. No he encontrado este comportamiento documentado por Microsoft en ninguna parte.

Entonces, la solución es, después de generar el manifiesto de implementación con MAGE.EXE, pero antes de firmarlo, elimine los elementos <file> para cualquier ensamblaje nativo. Los conjuntos nativos aún deben estar disponibles en la misma ubicación de implementación que el resto de los conjuntos requeridos por la aplicación ClickOnce.

En nuestro caso, automatizamos esto, ya que también automatizamos la generación del manifiesto de implementación con cada compilación de integración continua (a diferencia del uso del Asistente de publicación en Visual Studio 2010, que le da un poco más de control); tenemos un script de Powershell que invoca a MAGE.EXE para crear el manifiesto de implementación, algo más de Powershell para manipular el XML y eliminar el elemento <file> (realmente fácil con Powershell ... ¡buena suerte con un archivo por lotes!), luego invocamos MAGE.EXE para firmar el manifiesto.