一次单击的应用程序如何确定其应用程序身份? [英] How does a click-once application determine its application identity?

查看:67
本文介绍了一次单击的应用程序如何确定其应用程序身份?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个单击一次的应用程序,该应用程序经过正确签名,正确配置并可以自行安装,而不会出现任何问题。

I have a click-once application, which is correctly signed, correctly configured and installs itself without any problem.

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

It is set to run offline, but install from a specific URL, and if I download and run the setup.exe, it installs updates.

所以,基本上所有的工作都正常了……除了我无法打印出版本号,或者无法从代码中触发更新。如果尝试,我会感到恐惧:未设置应用程序身份。

So, it's basically all working... except I cannot print out the version number, or trigger an update from in code. If I try, I get the dreaded: 'Application identity is not set.'

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()

我未在调试模式下运行或未使用调试版本。

I am not running in debug mode, or using a debug build.

这是我的实际问题:

System.Deployment.Application 中的单击一次代码如何在运行时确定应用程序标识是什么?

How, does the click-once code in System.Deployment.Application, at runtime, determine what the application identity is?

因此,还有很多其他问题,但就我所知不是一个重复的问题,请不要将其重复。

So, there are whole lot other questions around this, but please don't close this as a duplicate, as far as I can tell it is not one.

以下是我不想要要解决的问题的列表:

Here's a list of things I do not want answers for:


  • 如何签署一个点击应用程序。

  • 如何在构建时设置应用程序标识。

  • 如何找到单击一次应用程序的位置

  • 如何在期间使单击一次应用程序正常工作>调试

  • 如何使用 ApplicationDeployment 检查更新。

  • How to sign a click-one application.
  • How to set the application identity as you build.
  • How to find where the click-once application is installed.
  • How to make a click-once application work while debugging.
  • How to check for updates using ApplicationDeployment.

很简单,完全单击一次应用程序在运行时的作用是 ,以便确定应用程序的身份。

Just very plainly, exactly what does a click-once application do, at runtime that lets it determine the application identity.

帮助!

我(因此徒劳无功)解决此问题的尝试产生了以下注释:

My (thus far fruitless) attempts to solve this have yielded these notes:

我敢肯定这与应用程序的启动方式有关,因为从命令行执行应用程序从未与单击一次一起工作。但是从开始菜单执行相同的应用程序将正确返回 IsNetworkDeployed 为true。

I'm certain this has something to do with how the application is launched, because executing applications from the command line has never worked with click-once; but executing the same application from the start menu will correctly return IsNetworkDeployed as true.

但是,我无法确定技术差异是什么,或者为什么一个人能够正确检测到安装而另一个却没有。 (或者确实,当其他应用程序没有明显区别时,为什么此特定应用程序无法从开始菜单运行)。

However, I've not been able to determine what the technical difference is, or why one detects the install correctly and one doesn't. (or indeed, why this specific application doesn't work from the start menu, when others with no obvious difference do).

我尝试过的操作没有任何区别包括:

Things I've tried that make no difference include:


  • 应用程序的工作目录。

  • 直接或通过启动应用程序.exe外壳程序

  • 从新快捷方式启动应用程序

进入开始菜单的 MyApplication.appref-ms; appref-ms只是安装路径的网址:

There is some kind magic to the 'MyApplication.appref-ms' that goes into the start menu; the appref-ms is just a url to the install path:

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

......以某种方式 启动应用程序的一次单击即可实例。

...which somehow launches a 'click once aware' instance of the application. But how?

推荐答案

我仍然很乐意接受一个答案,该答案解释了启动应用程序的实质如何设置应用程序上下文拥有一个身份,但是现在这是我最好的选择,对于以后以后发现此问题的任何人,这是怎么回事:

I'll still happily accept an answer that explains how the guts of launching the application actually sets the application context up with an identity, but for now here's my best stab at what's going on for anyone else who finds this question later:


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

  • ClickOnce applications are launched by hitting the install url, or by using the .appref-ms file on the start menu, which contains the url.

已为下载的文件调用 application / x-ms-application MIME类型处理程序,该处理程序启动了 ClickOnce感知实例

The application/x-ms-application MIME type handler is invoked for the downloaded file, which launches the 'ClickOnce aware' instance of the application.

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

At runtime, the ApplicationContext.Identity is used to determine what the ClickOnce details are, and setup the CurrentDeployment object.

据任何人所知,直接启动用于一个ClickOnce应用程序(在C:\Users\Administrato中r\AppData\Local\Apps\2.0\b107ee1 ...或任何安装文件夹)将始终返回 IsNetworkDeployed

As far as anyone knows, directly launching the deployed executable for a ClickOnce application (in C:\Users\Administrator\AppData\Local\Apps\2.0\b107ee1... or whatever the install folder is) will always return IsNetworkDeployed as false, and will not be able to self update.

实际上,这意味着:


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

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

To spawn a new 'ClickOnce aware' instance of your application launch internet explorer at its install url. You cannot pass command line arguments to it.

例如。

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 应用程序文件; URL包含在其中)

(if you want to find the URL, hunt through the start menu for the appref-ms file for the application; the url is contained in it)

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

...and how does the executable get launched with an identity?

不知道;但这似乎是任何人似乎都无法理解的:

No idea; but this is as far as anyone seems to ever have got with understanding it:

(tldr;魔术。可能与如何调用CreateProcess来使用生成应用程序有关ApplicationContext api,结合使用DFsvc.exe,DFshim.dll和DFdll.dll)

(tldr; magic. Probably something to do with how CreateProcess is invoked to spawn the appliciation using the ApplicationContext api, in some combination of DFsvc.exe. DFshim.dll and DFdll.dll)

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

(The rest of this information is taken from this old blog post by Ian Picknel: http://ianpicknell.blogspot.com.au/2010/03/launching-clickonce-application.html)


一旦部署清单已被
存储在Temporary Internet Files文件夹中,然后,Internet Explorer
尝试建立应如何处理(假定
和实际的).application扩展名的文件。它在HKCU\Software\Classes中检查用户特定的文件
类型,如果未能在其中找到
.application子项,则在$ b $检查计算机特定的文件类型。 b HKCR。通过这种方式,它确定.application扩展名
表示Application.Manifest文件。然后,它使用此信息来
检查特定于用户的HKCU\Software\Classes\Application.Manifest和
特定于计算机的HKCR keysApplication.Manifest密钥以建立CLSID
库处理Application.Manifest文件并产生
结果{98af66e4-aa41-4226-b80f-0b1a8f34eeb4}。最后,它在用户特定的
HKCU\软件\类\CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}和
机器特定的HKCR中查找
此CLSID \CLSID {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}
路径,用于确定.application文件由
C处理:\WINDOWS\system32\DFshim.dll。

Once the deployment manifest has been stored in the Temporary Internet Files folder, Internet Explorer then attempts to establish how it should handle the file with the (assumed and actual) .application extension. It checks the user-specific file types at HKCU\Software\Classes and, if it fails to find an .application sub-key there, checks for machine-specific file types at HKCR. Via this means it establishes that the .application extension denotes an Application.Manifest file. It then uses this information to check the user-specific HKCU\Software\Classes\Application.Manifest and machine-specific HKCR\Application.Manifest keys to establish the CLSID of a library which handles Application.Manifest files and yields the result {98af66e4-aa41-4226-b80f-0b1a8f34eeb4}. Finally, it looks up this CLSID in the user-specific HKCU\Software\Classes\CLSID{98af66e4-aa41-4226-b80f-0b1a8f34eeb4} and machine-specific HKCR\CLSID{98af66e4-aa41-4226-b80f-0b1a8f34eeb4} paths to establish that .application files are handled by C:\WINDOWS\system32\DFshim.dll.

这是事情开始变得有点复杂的地方。我之前说过
幕后没有发生魔术。好吧,尽管对于获取部署清单的过程来说确实是
,但大多数
当然对于一旦检索到部署清单后实际启动
ClickOnce应用程序的过程来说是不正确的$ b和处理程序DFshim.dll已被识别。

This is where things start to get a little complicated. I said earlier that no 'magic' was happening behind the scenes. Well, whilst that was true for the process of retrieving the deployment manifest it most certainly is not true of the process of actually launching the ClickOnce application once the deployment manifest has been retrieved and the handler, DFshim.dll, has been identified.

DFshim.dll在注册表中被描述为清单模拟处理程序
,尽管其文件属性将其描述为应用程序
部署支持库。它实现了Internet Explorer MIME
处理程序COM接口。它是一个本机的32位DLL,用Microsoft
Visual C ++ 2005编写,并在安装
.NET Framework 2.0时安装到C:\Windows\system32中。

DFshim.dll is described in the registry as the 'Manifest mime handler' although its file properties describe it as the 'Application Deployment Support Library'. It implements the Internet Explorer MIME handler COM interface. It is a native 32-bit DLL, written in Microsoft Visual C++ 2005, and was installed into C:\Windows\system32 when the .NET Framework 2.0 was installed.

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

DFshim.dll has a hard-coded reference to DFdll.dll, which it locates by checking the values of HKLM\SOFTWARE\Microsoft.NETFramework\InstallRoot (typically C:\Windows\Microsoft.NET\Framework) and the keys beneath HKLM\SOFTWARE\Microsoft.NETFramework\Policy\AppPatch (typically v2.0.50727, even if a later version of the Framework is installed). DFdll.dll too is a native 32-bit DLL written in Microsoft Visual C++ 2005.

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

DFdll.dll uses COM services exposed by DFsvc.exe, which is also located in the .NET Framework folder. DFsvc.exe is a standard .NET MSIL assembly. DFsvc contains a single Main method (within the System.Deployment.Application namespace) which simply calls the internal System.Deployment.Application.DFServiceEntryPoint.Initialize method within System.Deployment.dll. The Initialize method registers System.Deployment.Application.DeploymentServiceCom with COM via System.Runtime.InteropServices.RegistrationServices (i.e. it performs the equivalent of CoRegisterClassObject in COM) using the CLSID {33246f92-d56f-4e34-837a-9a49bfc91df3}. This is the means by which its services are made available to DFdll.dll.


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

The COM service exposed by System.Deployment.Application.DeploymentServiceCom delegates the majority of its methods to other non-ComVisible classes within the System.Deployment.Application namespace. For example, the public ActivateDeployment method calls ActivateDeployment on a new System.Deployment.Application.ApplicationActivator instance, the public CheckForDeploymentUpdate method calls CheckForDeploymentUpdate on System.Deployment.Application.SubscriptionStore, etc.

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

It is clear that the vast majority of the work surrounding the actual installation and launch of the ClickOnce application is undertaken by classes within the System.Deployment namespace, hosted within DFsvc.exe. DFshim.dll and DFdll.dll appear to primarily be responsible for arbitrating between the COM-based world of Internet Explorer and the .NET-based world of ClickOnce.

这篇关于一次单击的应用程序如何确定其应用程序身份?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆