Click-once应用程序如何确定其应用程序标识?

我有一个单击一次的应用程序,它已正确签名,正确配置并自行安装,没有任何问题。

它设置为脱机运行,但是从特定URL安装,如果我下载并运行setup.exe,它将安装更新。

所以,它基本上都在工作……除了我不能打印版本号,或从代码中触发更新。 如果我尝试,我会感到害怕:“应用程序标识未设置。”

2017-01-10 13:43:14.8367 ERROR System.Deployment.Application.InvalidDeploymentException: Application identity is not set. at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment() at LibDataAgent.Internal.Services.UpdateService.Deployment() System.Deployment.Application.InvalidDeploymentException: Application identity is not set. at System.Deployment.Application.ApplicationDeployment.get_CurrentDeployment() at LibDataAgent.Internal.Services.UpdateService.Deployment() 

我没有在调试模式下运行,也没有使用调试版本。

所以这是我的实际问题:

System.Deployment.Application中的click-once代码在运行时如何确定应用程序标识是什么?

所以,围绕这个还有很多其他问题,但请不要将其作为副本关闭,据我所知,它不是一个。

以下列出了我想要的答案:

  • 如何签署 click-one应用程序。
  • 如何在构建时设置应用程序标识。
  • 如何查找单击一次应用程序的安装位置。
  • 如何在调试时使单击一次应用程序工作。
  • 如何使用ApplicationDeployment检查更新。

非常简单地说,一次性点击应用程序在运行时确实执行了什么, 确定应用程序标识。

救命!

笔记

我(迄今为止没有结果)尝试解决这个问题已经产生了这些注释:

我确信这与应用程序的启动方式有关,因为从命令行执行应用程序从未使用过click-once; 但是从开始菜单执行相同的应用程序将正确返回IsNetworkDeployed为true。

但是,我无法确定技术差异是什么,或者为什么人们正确检测到安装,而不是。 (或者实际上,为什么这个特定的应用程序不能从开始菜单起作用,当其他人没有明显的区别时)。

我试过的事情没有任何区别包括:

  • 应用程序的工作目录。
  • 直接或通过shell启动应用程序.exe
  • 从新的快捷方式启动应用程序

进入开始菜单的’MyApplication.appref-ms’有一些神奇之处; appref-ms只是安装路径的URL:

 http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86 

…以某种方式启动应用程序的“单击一次识别”实例。 但是怎么样?

我仍然会愉快地接受一个解释,解释启动应用程序的内容实际上是如何使用身份设置应用程序上下文,但是现在这是我最好的选择,以便后来发现此问题的其他人发生了什么:

  • 通过点击安装URL或使用包含url的开始菜单上的.appref-ms文件启动ClickOnce应用程序。

  • 为下载的文件调用application/x-ms-application MIME类型处理程序,该文件启动应用程序的“ClickOnce aware”实例。

  • 在运行时, ApplicationContext.Identity用于确定ClickOnce详细信息,并设置CurrentDeployment对象。

  • 据大家所知,直接启动ClickOnce应用程序的部署可执行文件(在C:\ Users \ Administrator \ AppData \ Local \ Apps \ 2.0 \ b107ee1 …或安装文件夹中的任何内容)将始终IsNetworkDeployed返回为false,并且无法自我更新。

实际上,这意味着:

  • 您正在寻找安装文件夹和.exe的路径? 不要打扰。 即使你知道它在哪里,当你运行它时它也没有正确的ApplicationContext

  • 要生成应用程序的新“ClickOnce aware”实例,请在其安装URL上启动Internet Explorer。 您不能将命令行参数传递给它。

例如。

 var url = "http://s3-ap-southeast-1.amazonaws.com/blahblah/Dev/MyApplication.application#MyApplication.application, Culture=neutral, PublicKeyToken=fdasdfsafads, processorArchitecture=x86"; var psi = new ProcessStartInfo { FileName = @"iexplore", Arguments = $"\"{url}\"", }; Process.Start(psi); 

(如果要查找URL,请通过应用程序的appref-ms文件的开始菜单进行appref-ms ;其中包含URL)

…以及如何使用身份启动可执行文件?

不知道; 但这是任何人似乎都有理解它:

(tldr; magic。可能与在某些DFsvc.exe.DFshim.dll和DFdll.dll的组合中调用CreateProcess以使用ApplicationContext api生成应用程序有关。

(其余信息来自Ian Picknel撰写的这篇旧博文: http ://ianpicknell.blogspot.com.au/2010/03/launching-clickonce-application.html)

一旦部署清单存储在Temporary Internet Files文件夹中,Internet Explorer就会尝试使用(假定的和实际的).application扩展名来确定它应该如何处理该文件。 它检查HKCU \ Software \ Classes中的用户特定文件类型,如果在那里找不到.application子密钥,则在HKCR检查机器特定的文件类型。 通过这意味着它确定.application扩展名表示Application.Manifest文件。 然后,它使用此信息检查特定于用户的HKCU \ Software \ Classes \ Application.Manifest和特定于机器的HKCR \ Application.Manifest键,以建立处理Application.Manifest文件并生成结果的库的CLSID {98af66e4- aa41-4226-b80f-0b1a8f34eeb4}。 最后,它在用户特定的HKCU \ Software \ Classes \ CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}和机器特定的HKCR \ CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}路径中查找此CLSID确定.application文件由C:\ WINDOWS \ system32 \ DFshim.dll处理。

这是事情开始变得有点复杂的地方。 我之前说过,幕后没有“魔术”发生。 好吧,虽然在检索部署清单的过程中确实如此,但是一旦检测到部署清单并且已经识别出处理程序DFshim.dll,实际上启动ClickOnce应用程序的过程肯定不是这样。

DFshim.dll在注册表中被描述为’Manifest mime handler’,尽管它的文件属性将其描述为’Application Deployment Support Library’。 它实现了Internet Explorer MIME处理程序COM接口。 它是一个本机32位DLL,使用Microsoft Visual C ++ 2005编写,并在安装.NET Framework 2.0时安装到C:\ Windows \ system32中。

DFshim.dll有一个对DFdll.dll的硬编码引用,它通过检查HKLM \ SOFTWARE \ Microsoft.NETFramework \ InstallRoot(通常是C:\ Windows \ Microsoft.NET \ Framework)和HKLM下面的键来定位它SOFTWARE \ Microsoft.NETFramework \ Policy \ AppPatch(通常是v2.0.50727,即使安装了更高版本的Framework)。 DFdll.dll也是用Microsoft Visual C ++ 2005编写的本机32位DLL。

DFdll.dll使用DFsvc.exe公开的COM服务,该服务也位于.NET Framework文件夹中。 DFsvc.exe是标准的.NET MSIL程序集。 DFsvc包含一个Main方法(在System.Deployment.Application命名空间内),它只调用System.Deployment.dll中的内部System.Deployment.Application.DFServiceEntryPoint.Initialize方法。 Initialize方法使用CLSID {33246f92-d56f-4e34-837a-9a49bfc91df3}通过System.Runtime.InteropServices.RegistrationServices(即它在COM中执行等效的CoRegisterClassObject)向COM注册System.Deployment.Application.DeploymentServiceCom。 这是DFdll.dll可以使用其服务的方法。

System.Deployment.Application.DeploymentServiceCom公开的COM服务将其大多数方法委托给System.Deployment.Application命名空间中的其他非ComVisible类。 例如,公共ActivateDeployment方法在新的System.Deployment.Application.ApplicationActivator实例上调用ActivateDeployment,公共CheckForDeploymentUpdate方法在System.Deployment.Application.SubscriptionStore上调用CheckForDeploymentUpdate等。

很明显,围绕实际安装和启动ClickOnce应用程序的绝大多数工作都是由DF.vep.exe中托管的System.Deployment命名空间中的类承担的。 DFshim.dll和DFdll.dll似乎主要负责在基于COM的Internet Explorer世界和基于.NET的ClickOnce世界之间进行仲裁。