ClickOnce部署 - 文件关联未注册

时间:2011-06-27 05:58:47

标签: c# file deployment clickonce associations

所以这里是对问题的简要总结:

要点:

  

我设置了ClickOnce应用程序的fileAssociations,但是当我运行/更新我的程序时,它们没有注册(例如,.bvr文件我我试图关联没有图标,我不能双击它们来启动我的应用程序)

额外信息:

我首先尝试转到属性 - >发布 - >选项 - >文件关联并从那里设置我的关联。尝试失败后,我尝试直接在app.manifest中设置它:

<fileAssociation
xmlns="urn:schemas-microsoft-com:clickonce.v1"
extension=".bvr"
description="Behavior File"
progid="GGS.Behavior"
defaultIcon="bvrico.ico"
/>

我读过这么多关于此事的文章,我开始感到沮丧。一些信息:

  1. 我已将其设置为完全信任的应用程序(在安全性下 - &gt;启用ClickOnce安全设置 - &gt;这是一个完全信任的应用程序)
  2. 我使用的是.NET 4.0和Visual Studio 2010
  3. 启用“离线”模式
  4. 我也处理通过AppDomain传递的数据,但我怀疑这确实改变了什么。

    我想知道文件关联只能在安装时设置。

    无论如何,我真的很感激这个问题的一些见解。我真的很喜欢我项目中的文件关联。

    提前感谢大家。

    PS: 在Windows XP和Windows 7上测试。

    编辑:我也在微软上发布了这个,顺便说一句。

    http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/d610cd55-f3c7-4775-a417-251261832200

    如果有人想在那里发布答案。我真的无法想出这个。 :d

6 个答案:

答案 0 :(得分:6)

如果您尝试注册的文件类型先前已在其他程序(如记事本)中注册,或者甚至在记事本中打开,那么我发现让它工作的唯一方法是从注册表中删除文件类型2位置,然后重新启动。之后发布您的应用程序的更新,如果它的那种问题你的状态良好。

HKEY_CURRENT_USER \软件\微软\的Windows \ CurrentVersion \ Explorer中\ FileExts \ .bvr

HKEY_CLASSES_ROOT \ .bvr

重新启动

向您的应用发布更新。

答案 1 :(得分:2)

在ClickOnce部署后使此功能正常工作的唯一方法是在代码中添加/更新多个注册表项。见下文。

已经8年了,甚至在带有Windows 10的最新版本的Visual Studio 2019中, ClickOnce部署中的文件关联设置仍然不起作用。我怀疑这是Windows版本的问题,因为Microsoft似乎会更改每个新版本的Windows在注册表中存储文件关联的方式。但是无论如何,对于当前的Windows版本,Visual Studio和ClickOnce应该 工作 。事实并非如此。

在完成我的ClickOnce应用的全新安装后,我找到了一个用于文件扩展名的注册表项:

Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.xxxxxx

它为ProgID添加了此注册表项:

Computer\HKEY_CLASSES_ROOT\xxxxxxxxxxx

但是它没有从文件扩展名添加对ProgID的引用。

这两个条目在Windows 10中不执行任何操作。它不显示图标,打开带有该扩展名的文件时不打开ClickOnce应用程序,并且在“打开方式”列表中不显示任何ClickOnce选项(作为注释器)建议)。请注意,上面的注册表项是由部署创建的,但不包含对ClickOnce应用程序或在ClickOnce属性中设置的ProgID的引用。实际上,该文件扩展名注册表项中引用的唯一应用程序是“ OpenWith.exe”。

解决方案

花了两天时间研究这个问题并将各种想法融合在一起,下面的解决方案是我发现唯一可行的解​​决方案。每次您的应用程序启动时(或至少在安装/升级之后立即执行),只需执行SetAssociation(),即可解决所有Windows版本中的文件关联问题。

using Microsoft.Win32;
using System;
using System.Collections.Generic;

namespace MyLibrary
{
    public class FileAssociations
    {
        [System.Runtime.InteropServices.DllImport("Shell32.dll")]
        private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

        private const int SHCNE_ASSOCCHANGED = 0x8000000;
        private const int SHCNF_FLUSH = 0x1000;

        public static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
        {
            bool madeChanges = false;
            madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
            madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
            madeChanges |= SetKeyDefaultValue($@"Software\Classes\{progId}\shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
            return madeChanges;
        }

        private static bool SetKeyDefaultValue(string keyPath, string value)
        {
            using (var key = Registry.CurrentUser.CreateSubKey(keyPath))
            {
                if (key.GetValue(null) as string != value)
                {
                    key.SetValue(null, value);
                    return true;
                }
            }

            return false;
        }
    }
}

然后在程序启动时执行此操作。 Environment.GetCommandLineArgs()中的第一项包含您exe的完整路径:

string[] args = Environment.GetCommandLineArgs();
FileAssociations.SetAssociation(FileExtension, ProgID, FileExtensionDescription, args[0]);

我发现此方法的唯一问题是,如果您的文件关联直接执行.exe,则ClickOnce自动更新将不起作用,因为更新信息存储在“开始”菜单快捷方式中,而不是存储在已安装的应用程序文件中。

与您提出的问题不同,但是为了解决此问题,如果应用程序直接使用.exe启动,我以编程方式找到了ClickOnce应用程序(扩展名为.appref-ms)的“开始”菜单快捷方式,然后使用该路径(而不是.exe)重新启动应用程序,将发送给您的.exe的原始命令行参数传递给它,然后在重新启动时,我使用 AppDomain.CurrentDomain.SetupInformation检索THOSE参数。 ActivationArguments.ActivationData

答案 2 :(得分:1)

您确定以下项目未出现在打开方式... 文件选项 - Clickonce应用程序部署支持库中,并带有问号图标吗?尝试将其设置为默认值。

我遇到了与你相同的问题,但我注意到在安装我的应用程序后出现了这个奇怪的选项。经过如此多的尝试和谷歌搜索,我尝试了一个简单的事情 - 同意使这个 Clickonce应用程序部署支持库成为所需文件类型的默认值。和ta da!该文件的图标变为我的应用程序图标,它启动了我的应用程序。我想事情是我想要的文件类型已经与记事本相关联,所以ClickOnce拒绝覆盖此设置。

答案 3 :(得分:0)

ClickOnce不会以通常的方式传递命令行参数,而是通过

AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData

因此,在您的应用程序启动时,您需要检查天气是否包含任何字符串并相应地修改您的启动行为。

这是因为ClickOnce应用程序是通过服务器上的部署清单启动的,而不是通过.exe启动的。顺便说一句:通过属性设置文件关联 - &gt;发布 - &gt;选项 - &gt;文件关联应该可以正常工作。

修改(我是如何创建示例应用的)

  • 创建Windows窗体应用
  • 激活ClickOnce-security设置,选择完全受信任的应用程序
  • 在ClickOnce选项中 - &gt;描述,设置发布者,套件和产品名称
  • 在ClickOnce选项中 - &gt;文件关联添加新扩展名
  • 发布应用程序,安装应用程序,测试打开文件时启动的天气(确实如此)

所有未提及的设置都没有被触及......这就是我所做的一切!

似乎这就是你所做的 - 也许尝试创建一个简单的测试应用程序,看看它是否适合你。由于这个答案并没有真正回答你的问题,请在完成后告诉我,以便我可以将其删除。

答案 4 :(得分:0)

当我们增加版本号并在不同的子文件夹下发布应用程序时,会发生这种情况。 例如

  • 版本1.0已发布到\\server\product\version 1.0\
  • 2.0版已发布到\\server\product\version 2.0\

我按照@EvAlex的回答,出现了一个对话框,我点击了“详细信息”按钮,打开了一个日志文件。在日志文件中,我注意到该程序试图从旧版本的路径下载,它所寻找的路径仍为\\server\product\version 1.0\

然后我意识到它应该是注册表中的内容。

我打开了regedit,并搜索了product(这是我的产品名称),并找到了日志错误在以下几个键下投诉的路径:

  • HKEY_CURRENT_USER \ Software \ Classes.myext
  • HKEY_CURRENT_USER \ Software \ Classes下\ MyProgId
  • HKEY_CLASSES_ROOT \ MyProgId

我删除了这些密钥,并重复了Open With操作,图标又回来了,然后就像魅力一样。

所以看起来应用程序没有被彻底卸载,或者由于某些未知原因而出现ClickOnce更新这些密钥的错误。

答案 5 :(得分:0)

我发现Alan的帖子最有帮助。它的工作原理是我在我的一台计算机上为我写的,但在另一台计算机上它并没有让我在那里。我希望只是在他的帖子中添加评论,但Stack Overflow说我没有这个名声点。

如果您需要,希望您仍然可以在这里找到它。

我还必须为每个扩展名映射删除如下所示的键:

HKEY_CLASSES_ROOT\AppName.FileType.0

将此添加到Adam,删除其他.ext键可解决我的其他计算机上的问题。