如何在安装后手动注册ClickOnce文件关联?

微软的ClickOnce部署系统提供了一个易于使用的文件关联pipe理器, 内置于Visual Studio部署过程中 。 开发人员最多可以添加8个文件关联,当用户运行ClickOnce安装程序时,这些文件关联将自动与其应用程序相关联。

我想进一步,但是: 我想让用户在我的应用程序安装后手动添加或删除额外的文件关联。

我有两个完成这个动机的动机:

  • 我不会“强制”用户上的其他文件关联,这就是通过ClickOnce部署处理文件关联的方式。
  • 用户可以在闲暇时添加或删除自己独特的文件关联。

棘手的部分:将文件types与可执行文件直接关联,与ClickOnce部署不兼容

与传统的Windows应用程序不同,ClickOnce应用程序不是通过可执行文件直接启动的。 相反,它们是通过特殊的.appref-ms快捷方式启动的,该快捷方式在后台处理ClickOnce魔法(自动更新,在%LOCALAPPDATA%中的混淆目录中查找可执行文件等)。

如果通过其可执行文件直接打开ClickOnce部署的应用程序,则会禁用自动更新,并且ClickOnce特定的方法将不再起作用。 正因为如此,传统的registry文件关联对我的用例来说是不可能的。

Visual Studio如何处理ClickOnce文件关联

下图展示了Visual Studio 2010内置的ClickOnce文件关联pipe理器。 此信息存储在应用程序的.manifest文件中,并在安装后添加到Windowsregistry中。

VS2010的ClickOnce文件关联管理器

我已经通过我的registry进行了一些挖掘,并确定了ClickOnce安装程序所做的几个条目,以将文件types与ClickOnce部署的应用程序相关联。

在registry中find的ClickOnce文件types关联的示例registry项:

rundll32.exe dfshim.dll, ShOpenVerbExtension {ae74407a-1faa-4fda-9056-b178562cf98f} %1

其中{ae74407a-1faa-4fda-9056-b178562cf98f}是在关联应用程序的registry中的其他几个位置使用的GUID。

我的目标是要了解必须将哪些信息添加到registry(以编程方式)手动将文件与ClickOnce部署的应用程序相关联。

任何帮助表示赞赏!

您可以使用Windows Sysinternals Process Monitor(以前称为RegMon)来计算要添加的registry项。

捕获事件,当您使用ClickOnce安装您的应用程序与默认的文件关联。 它会logging所有的registry操作(大量)。

您需要使用一些filter来轻松识别registry项。

好吧,遇到同样的问题后,做一些认真的挖掘,我想我有一个解决scheme。 Evan Wondrasek与rundll命令走在了正确的道路上,我能够在testing环境中获得以下工作。

本质上,Uri Abramson是正确的,rundll.exe命令中的Guid是对clickonce应用程序的引用,但它不会出现在registry中的任何其他位置。 它所引用的实际上是HKCU\Software\Classes的其他Keys。

要使文件参考起作用,首先需要为您的应用程序使用ProgID 。 据我所知,这可以是任何你想要的,或者任何你通常在Visual Studio的ClickOnce发布菜单中设置的。

您还需要创build一个新的Guid,并了解应用程序参考(.appref-ms)文件的内容。

对于我的例子,我将使用以下内容:

 ProgId: FASERVER.TestApp Guid: ce6b2c69-ec54-4182-a87f-74c5dfe1a03e AppRefFileContents: http://SomeAddress.SomeDomain/TestApp/TestApp.application#TestApp.application, Culture=neutral, PublicKeyToken=df31b9b884b9be10, processorArchitecture=x86 

请在下面的代码中使用上面的值。

首先,使用以下string在HKCU\Software\Classes下创build一个名为FASERVER.TestApp的新registry项:

 (Default) = SomeFileType AppId = TestApp.application, Culture=neutral, PublicKeyToken=df31b9b884b9be10, processorArchitecture=x86 DeploymentProviderUrl = http://SomeAddress.SomeDomain/TestApp/TestApp.application Guid = {ce6b2c69-ec54-4182-a87f-74c5dfe1a03e} 

一旦你设置了这些值,创build两个新的subKeys shellshellex

设置shell(Default)open 。 然后创build一个名为openshell的subKey和一个open的subKey作为command 。 将command(Default)值设置为以下内容:

 rundll32.exe dfshim.dll, ShOpenVerbExtension {ce6b2c69-ec54-4182-a87f-74c5dfe1a03e} %1 

创build一个名为IconHandlershellex IconHandler ,并将其(Default)值设置为{ce6b2c69-ec54-4182-a87f-74c5dfe1a03e}

导航到HKCU\Software\Classes\CLSID并使用以下string创build一个新的密钥{ce6b2c69-ec54-4182-a87f-74c5dfe1a03e}

 (Default) = Shell Icon Handler For Tif File AppId = TestApp.application, Culture=neutral, PublicKeyToken=df31b9b884b9be10, processorArchitecture=x86 DeploymentProviderUrl = http://SomeAddress.SomeDomain/TestApp/TestApp.application IconFile = YourIconFile.ico 

注意:您的图标必须位于ClickOnce项目中。

现在使用以下值在名为InProcServer32 {ce6b2c69-ec54-4182-a87f-74c5dfe1a03e}下创build一个{ce6b2c69-ec54-4182-a87f-74c5dfe1a03e}

 (Default) = dfshim.dll ThreadingModel = Apartment 

最后,我们需要将以前的键与我们所需的文件关联关联起来。 为此,导航到HKCU\Software\Classes ,并为每个所需的文件扩展名执行以下操作。

设置FileExtstring,如下所示:

 (Default) = FASERVER.TestApp AppId = TestApp.application, Culture=neutral, PublicKeyToken=df31b9b884b9be10, processorArchitecture=x86 DeploymentProviderUrl = http://SomeAddress.SomeDomain/TestApp/TestApp.application Guid = {ce6b2c69-ec54-4182-a87f-74c5dfe1a03e} 

而已! 你应该做的。

请注意,这不会将您的应用程序设置为该文件types的默认程序,而只会在“打开方式”菜单中添加“ClickOnce应用程序支持库”条目。

希望这适用于除我以外的其他人,并为冗长的例子感到抱歉。

关于命令呢?

http://support.microsoft.com/kb/184082


assoc /?

显示或修改文件扩展名关联

ASSOC [.ext [= [fileType]]]

.ext指定将文件types与fileType关联的文件扩展名指定与文件扩展名关联的文件types

input不带参数的ASSOC来显示当前的文件关联。 如果只用一个文件扩展名调用ASSOC,它将显示该文件扩展名的当前文件关联。 不指定文件types,命令将删除文件扩展名的关联。


文件关联可以是机器级别或用户级别 – 通常情况下,HKCR区域是用于机器级别的文件关联。 “HKCU /软件/类”区域中的东西是用户定制的每个用户的东西(或者您为他们定制的东西)。 像“联合”的东西将工作在XP,7,可能赢了8(虽然我还没有使用这个CMD的胜利8呢)。

如果你想手动注册文件关联,它不是ClickOnce的业务。 您可以手动将registry项添加到设置文件关联。 如果您想删除clickonce设置的关联,只需删除registry项即可。

  private static void SetFileAssociation(string icon, string application, string openArg, string extension , string progId , string description ) { Trace.WriteLine("-----Create File Association-----"); RegistryKey classesKey = Registry.CurrentUser.OpenSubKey(@"Software\Classes", true); classesKey.CreateSubKey(extension).SetValue(string.Empty, progId); RegistryKey progKey = classesKey.CreateSubKey(progId); if (description != null) { progKey.SetValue(string.Empty, description); } if (icon != null) { progKey.CreateSubKey("DefaultIcon").SetValue(string.Empty, icon); } progKey.CreateSubKey(@"Shell\Open\Command").SetValue(string.Empty, application + openArg); Trace.WriteLine("-----Finish File Association-----"); } 

解决方法:您可以将位于以下位置的ClickOnce应用程序的快捷方式关联:

 C:\Users\[Your username]\AppData\Roaming\Microsoft\Windows\Start Menu\[Program folder]\[Shortcut name]