La actualización del manifiesto de implementación para una aplicación ClickOnce da como resultado que falte el elemento <compatibleFrameworks>, requerido en 4.0

Estoy trabajando en la automatización del instalador para una aplicación .NET 4.0 ClickOnce WPF, que necesita algunos elementos para configurar en elapp.config expediente. He pasado por el espinoso proceso de encontrar pasos específicos que debo seguir usandoMage.exe (es decir, actualice y vuelva a firmar los manifiestos de aplicación y despliegue) y ahora estoy intentando automatizarlo para la instalación.

Opté por usar.desplegar extensión para minimizar problemas conIIS/ Los mecanismos de seguridad de Internet Explorer, por lo que esencialmente el algoritmo es el siguiente (basado enFirmar y volver a firmar los manifiestos en ClickOnce (Saurabh Bhatia) yActualice la configuración de una aplicación ClickOnce WPF usando Mage o MageUI, como fuentes primarias entre otras):

Ve a la\Application Files\App_%HighestVersion%\ carpetaretirar.desplegar extensión para archivos que lo tienencorrermage -u %app%.exe.manifest -cf cert.pfxRestaurar.desplegar extensióncorrermage -u %app%.application -appm %app%.exe.manifest -cf cert.pfxDupdo%app%.application 2 niveles hasta..\.. - raíz de despliegue)

Eso funciona perfectamente si se hace manualmente. Puedo correr un.cmd archivo, personalizado para entornos específicos (rutas, etc.), pero luego necesitaría incluirmage.exe en la implementación, y si Microsoft nos permite hacerlo es una pregunta abierta para mí. Por lo tanto, estoy tratando de realizar acciones similares en elInstaller clase:

X509Certificate2 ct = new X509Certificate2(sPathCert);

//  .. Remove .deploy extension (for files in the sPathApp folder).

sPathMft = Directory.GetFiles(sPathApp, "*.exe.manifest")[0];
ApplicationManifest am = ManifestReader.ReadManifest( "ApplicationManifest", sPathMft, false ) as ApplicationManifest;
if (am == null)
    throw new ArgumentNullException("AppManifest");
am.ResolveFiles();
am.UpdateFileInfo( );
ManifestWriter.WriteManifest(am, sPathMft);
SecurityUtilities.SignFile(ct, null, sPathMft);

//    .. Restore .deploy extensions to files touched above.

sPathMft = Directory.GetFiles(sPathApp, "*.application")[0];
DeployManifest dm = ManifestReader.ReadManifest("DeployManifest", sPathMft, false) as DeployManifest;
if (dm == null)
    throw new ArgumentNullException( "DplManifest" );
dm.ResolveFiles();
dm.UpdateFileInfo();
ManifestWriter.WriteManifest(dm, sPathMft);
SecurityUtilities.SignFile(ct, null, sPathMft);

File.Copy(sPathMft, sPathBin + "\\" + dm.AssemblyIdentity.Name, true);

Ahora, aquí está el kicker. Todo funciona perfectamente con la excepción del paso 5. Cuando la aplicación se descarga en la máquina del usuario, hay un problema con el manifiesto de implementación:

El manifiesto de despliegue no es semánticamente válido.Falta el manifiesto de implementación <compatibleFrameworks>.

De hecho, esta sección ya no está presente (sin embargo, estaba en la aplicación% app% .application original!). Un resultado similar se describe enClickOnce - Errores de .NET 4.0: "El manifiesto de implementación no es semánticamente válido" y "Falta el manifiesto de implementación <compatibleFrameworks>", pero es el resultado de un proceso diferente (msbuild). Esta sección es nueva (y se requiere) para los manifiestos 4.0, así que mi única conjetura es que de alguna manera cuando ManifestWriter persiste los cambios en el disco, ¿lo hace de una manera 3.5? Revisé tres veces que se usó una biblioteca correcta (C: \ Archivos de programa (x86) \ Referencias de referencia \ Microsoft \ Framework.NETFramework \ v4.0 \ Microsoft.Build.Tasks.v4.0.dll).¿Lo que da?

En lugar de una respuesta hasta ahora, intenté agregar la sección faltante manualmente:

dm.CompatibleFrameworks.Clear(); // Unnecessary as dm.CompatibleFrameworks.Count == 0 indeed!
CompatibleFramework cf = new CompatibleFramework();
cf.Version= "4.0";
cf.SupportedRuntime = "4.0.30319";
cf.Profile= "Client";
dm.CompatibleFrameworks.Add(cf);
cf = new CompatibleFramework();
cf.Version = "4.0";
cf.SupportedRuntime = "4.0.30319";
cf.Profile = "Full";
dm.CompatibleFrameworks.Add(cf);

Pero eso no tiene efecto, no importa donde coloque este código, antesdm.ResolveFiles (), dm.UpdateFileInfo () oManifestWriter.WriteManifest (..)!

Mi resultado es similar a las preguntas de desbordamiento de pilaMageUI.exe elimina el elemento compatibleFrameworks o¿Por qué Mage.exe no genera un atributo compatibleFrameworks? oMageUI.exe no incluye un elemento compatibleFrameworks, pero no estoy usandomageui, mage o inclusomsbuild ¡en absoluto!

¿Que esta pasando?

Respuestas a la pregunta(2)

Su respuesta a la pregunta