我正在为 .NET 4.0 ClickOnce WPF 应用程序自动化安装程序,该应用程序需要在app.config文件中设置一些项目。我已经经历了寻找使用Mage.exe必须遵循的特定步骤的棘手过程(即更新和重新签署应用程序和部署清单),现在正尝试将其自动化以进行安装。
我选择使用.deploy扩展来最大程度地减少IIS / Internet Explorer 安全机制的问题,所以基本上算法如下(基于ClickOnce 中的签名和重新签名清单(Saurabh Bhatia)和使用 Mage 更新 ClickOnce WPF 应用程序的配置或 MageUI,作为主要来源):
- 转到
\Application Files\App_%HighestVersion%\
文件夹 - 删除具有它的文件的.deploy扩展名
- 跑
mage -u %app%.exe.manifest -cf cert.pfx
- 恢复.deploy扩展
- 跑
mage -u %app%.application -appm %app%.exe.manifest -cf cert.pfx
- 向上复制
%app%.application
2 个级别(到..\..
- 部署根目录)
如果手动完成,那效果很好。我可以运行一个.cmd文件,针对环境细节(路径等)进行定制,但随后我需要将其包含mage.exe
在部署中,微软是否允许我们这样做对我来说是一个悬而未决的问题。因此,我试图在Installer
课堂上执行类似的操作:
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);
现在,这是踢球者。除第 5 步外,一切正常。当应用程序下载到用户计算机时,部署清单出现问题:
- 部署清单在语义上无效。
- 部署清单缺少 <compatibleFrameworks>。
实际上,这部分不再存在(但是,它在原始的 %app%.application 中!)。ClickOnce - .NET 4.0 错误中描述了类似的结果:“部署清单在语义上无效”和“部署清单缺少 <compatibleFrameworks>”,但它是不同过程 (msbuild) 的结果。这部分是 4.0 清单的新部分(并且是必需的),所以我唯一的猜测是,当 ManifestWriter 以某种方式将更改持久保存到磁盘时,它会以 3.5 的方式进行吗?我三次检查是否使用了正确的库(C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Microsoft.Build.Tasks.v4.0.dll)。 是什么赋予了?
到目前为止,我尝试手动添加缺少的部分来代替答案:
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);
但这没有任何效果,无论我将这段代码放在 dm.ResolveFiles( )、dm.UpdateFileInfo( )还是ManifestWriter.WriteManifest(..)之前的位置!
我的结果类似于堆栈溢出问题MageUI.exe 删除 compatibleFrameworks 元素或为什么 Mage.exe 不生成 compatibleFrameworks 属性?或MageUI.exe 不包含 compatibleFrameworks 元素,但我没有使用 mageui
,mage
甚至根本没有使用msbuild
!
这是怎么回事?