我正在致力于自动化 .NET 4.0 ClickOnce WPF 应用程序的安装程序,该应用程序需要在应用程序配置文件。我经历了寻找必须遵循的具体步骤的棘手过程Mage.exe http://msdn.microsoft.com/en-us/library/acz3y3te.aspx(即更新并重新签署应用程序和部署清单),现在正在尝试自动化安装。
我选择使用.deploy扩展以尽量减少问题IIS http://en.wikipedia.org/wiki/Internet_Information_Services/Internet Explorer安全机制,所以本质上算法如下(基于在 ClickOnce 中签署和重新签署清单 (Saurabh Bhatia) http://blogs.msdn.com/b/vsto/archive/2009/04/29/signing-and-re-signing-manifests-in-clickonce.aspx and 使用 Mage 或 MageUI 更新 ClickOnce WPF 应用程序的配置 http://www.eggheadcafe.com/tutorials/xaml/a8788ed5-c1b5-41d5-b49c-ea4760c3b820/update-configuration-of-a-clickonce-wpf-application-using-mage-or-mageui.aspx,作为主要来源):
- 前往
\Application Files\App_%HighestVersion%\
folder
- Remove .deploy具有该扩展名的文件
- Run
mage -u %app%.exe.manifest -cf cert.pfx
- Restore .deploy扩大
- Run
mage -u %app%.application -appm %app%.exe.manifest -cf cert.pfx
- Copy
%app%.application
向上 2 级(至..\..
- 部署根)
如果手动完成,效果非常好。我可以运行一个.cmd文件,根据环境细节(路径等)定制,但是我需要包括mage.exe
在部署中,微软是否允许我们这样做对我来说是一个悬而未决的问题。因此,我试图在Installer
class:
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 步之外,一切都运行良好。当应用程序下载到用户的计算机时,部署清单出现问题:
事实上,该部分已不再存在(但是,它位于原始的 %app%.application 中!)。类似的结果描述于ClickOnce - .NET 4.0 错误:“部署清单在语义上无效”和“部署清单缺少 ” http://blogs.msdn.com/b/msiclickonce/archive/2010/08/03/clickonce-net-4-0-errors-quot-deployment-manifest-is-not-semantically-valid-quot-and-quot-deployment-manifest-is-missing-lt-compatibleframeworks-gt-quot.aspx,但是是不同进程(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( ) or ManifestWriter.WriteManifest(..)!
我的结果类似于 Stack Overflow 问题MageUI.exe 删除 CompatibleFrameworks 元素 https://stackoverflow.com/questions/6186282/ or 为什么 Mage.exe 不生成兼容框架属性? https://stackoverflow.com/questions/2654320/ or MageUI.exe 不包含兼容的Frameworks 元素 https://stackoverflow.com/questions/3471194/,但我没有使用mageui
, mage
甚至msbuild
at all!
这是怎么回事?