当前位置: 首页 > 编程语言 > C#

UpdatingthedeploymentmanifestofaClickOnceapplicationprogrammaticallyresultsinmissingelements,whichisrequiredin4.0Share

时间:2023-04-10 20:34:14 C#

AddingupdatethedeploymentmanifestofaClickOnceapplicationprogrammaticallyresultsmissingelements,whichisrequiredin4.0Required我是尝试自动安装需要在app.config文件中设置某些项目的.NET4.0ClickOnceWPF应用程序。我经历了使用Mage.exe的棘手过程来找到我必须遵循的特定步骤(即更新和重新签署应用程序和部署清单),现在我正在尝试自动安装它。我选择使用.deploy扩展来最小化IIS/InternetExplorer安全机制的问题,所以算法基本上如下(基于ClickOnce(SaurabhBhatia)中的签名和重新签名清单以及ClickOnceWPF应用程序的更新配置使用Mage或MageUI作为主要来源等):转到ApplicationFilesApp_%HighestVersion%文件夹删除包含它的文件的.deploy扩展名运行mage-u%app%.exe.manifest-cfcert.pfx恢复.deployextensionrunmage-u%app%.application-appm%app%.exe.manifest-cfcert.pfxCopy%app%.application2levels(to....-deploymentroot)如果手动完成,这将完美运行.我可以运行.cmd文件,根据环境细节(路径等)自定义它,但我需要在部署中包含mage.exe,微软是否会让我们这样做对我来说是一个悬而未决的问题。因此,我正在尝试在Installer类中执行类似的操作:X509Certificate2ct=newX509Certificate2(sPathCert);//..删除.deploy扩展名(对于sPathApp文件夹中的文件)。sPathMft=Directory.GetFiles(sPathApp,"*.exe.manifest")[0];ApplicationManifestam=ManifestReader.ReadManifest("ApplicationManifest",sPathMft,false)asApplicationManifest;如果(am==null)抛出新的ArgumentNullException("AppManifest");am.ResolveFiles();am.UpdateFileInfo();ManifestWriter.WriteManifest(am,sPathMft);SecurityUtilities.SignFile(ct,null,sPathMft);//..恢复上面提到的文件的.deploy扩展名。sPathMft=Directory.GetFiles(sPathApp,"*.application")[0];DeployManifestdm=ManifestReader.ReadManifest("DeployManifest",sPathMft,false)asDeployManifest;如果(dm==null)抛出新的ArgumentNullException(“DplManifest”);dm.ResolveFiles();dm.UpdateFileInfo();ManifestWriter.WriteManifest(dm,sPathMft);SecurityUtilities.SignFile(ct,null,sPathMft);文件.副本PathMft,sPathBin+"\"+dm.AssemblyIdentity.Name,true);现在,问题来了除了第5步外,一切正常。当应用程序下载到用户计算机时,部署清单出现问题:事实上,这部分不再存在(但是,它在原始的%app中%。应用!)。ClickOnce-.NET4.0错误中描述了类似的结果:“部署清单在语义上无效”和“部署清单丢失”,但这是不同进程(msbuild)的结果。这部分是4.0清单的新部分(并且是必需的),所以我唯一的猜测是当ManifestWriter不断更改为磁盘时,它会像在3.5中那样吗?我三次检查我使用的库是否正确(C:\ProgramFiles(x86)\ReferenceAssemblies\MicrosoftFramework.NETFrameworkv4.0Microsoft.Build.Tasks.v4.0.dll)。是什么赋予了?到目前为止,我已经尝试手动添加缺失的部分来代替答案:dm.CompatibleFrameworks.Clear();//不必要,因为dm.CompatibleFrameworks.Count==0确实!CompatibleFrameworkcf=newCompatibleFramework();cf.Version="4.0";cf.SupportedRuntime="4.0.30319";cf.Profile="客户";dm.CompatibleFrameworks.Add(cf);cf=newCompatibleFramework();cf.Version="4.0";cf.SupportedRuntime="4.0.30319";cf.Profile="完整";dm.CompatibleFrameworks.Add(cf);但是在dm.ResolveFiles()、dm.UpdateFileInfo()或ManifestWriter.WriteManifest(..)之前,无论我在哪里放置这段代码,这些都没有任何效果!我的结果类似于StackOverflow问题MageUI.exeremovescompatibleFrameworkselement或Whydoesn'tMage.exegeneratecompatibleFrameworksattribute?或者MageUI.exe不包含compatibleFrameworks元素,但我根本不使用mageui、mage甚至msbuild!这是怎么回事?我自己想出来了。罪魁祸首是ManifestReader.ReadManifest("DeployManifest",sPathMft,true)。MSDN说,[preserveStream参数]“指定是否在生成的清单对象的InputStream属性中保留输入流。ManifestWriter使用它来重建未在对象表示中表示的输入。撇开写法不说,自己设置true是不行的:dm.CompatibleFrameworks.Count还是0,现在加上CompatibleFramework项就有效果了!对于同一条船上的其他人,我在dm.ResolveFiles()之前这样做:是调用法师(直接或从.cmd文件),因为我们似乎能够重新分发它。我还添加了以下部分,这对问题本身没有影响,但对于关注以下内容的任何人来说可能非常重要相同路径(/client为部署根,可自定义):dm.DeploymentUrl=string.Format("http://{0}/{1}/client/{1}.application",Dns.GetHostName(),Context.Parameters[scTokVirtDir]);dm.UpdateMode=UpdateMode.Background;dm.UpdateUnit=UpdateUnit.Weeks;dm.UpdateInterval=1;dm.UpdateEnabled=true;我还需要添加CompatibleFrameworks。我还尝试添加CompatibleFrameworks,例如这(这不起作用)dm.CompatibleFrameworks.Add(...);我的解决方案是:dm.TargetFrameworkMoniker=".NETFramework,Version=v4.0";在此之后,清单生成是正确的。注意,如果你在WriteManifest之前设置了TargetFrameworkMoniker,会有两次,你的应用程序文件被损坏了。这是我的解决方案:以上是C#学习教程:以编程方式更新ClickOnce应用程序的部署清单将导致缺少元素,这是4.0中的要求。分享完整内容,如果对大家有用还需要了解更多C#学习教程,希望大家多多关注---DeployManifestdm=ManifestReader.ReadManifest("DeployManifest",applicationFileName,false)asDeployManifest;dm.ResolveFiles();//做事..dm.UpdateFileInfo();ManifestWriter.WriteManifest(dm,applicationFileName);dm.TargetFrameworkMoniker=".NETFramework,Version=v4.0";ManifestWriter.WriteManifest(dm,applicationFileName);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢