Visual Studio 扩展在调试时工作,但当我安装 VSIX 时它不工作
Visual Studio Extension works while debugging but when I Install the VSIX it is not working
我正在尝试用 C# 制作一个 VSIX 插件。当我处于开发模式时,该插件工作正常。但是当我尝试安装插件时,即通过双击 VSIX,它不起作用。
我已经阅读了一些文档,有些人说要打包然后进行安装。但是当我将“生成 .pkgdef 文件”选项设置为“真”时,我收到类似“CreatePkgDef:错误:ArgumentException:在此程序集中找不到 Visual Studio 注册属性”的错误。并且程序集应包含程序集 'Microsoft.VisualStudio.Shell.Framework' 版本 '16.0.0.0'
中定义的属性 'Microsoft.VisualStudio.Shell.RegistrationAttribute' 的实例
基本上我想部署我的 VSIX。我该怎么做?有人可以帮忙吗?
谢谢。
我遇到了真正的问题。实际上我正在使用 ITeamExplorerNavigationItem2 在团队资源管理器中添加一个按钮。
我正在使用 属性 public System.Drawing.Image 图像来控制按钮图标。
public System.Drawing.Image Image => null // Button comes up without any button icon
public System.Drawing.Image Image => System.Drawing.Image.FromFile("MyImage.png"); // button does not show up in the team explorer
我怀疑的是,在调试期间它正在寻找“MyImage.png”的路径,但是在 运行 时图像没有打包到 VSIX,所以它没有找到.png 路径,随后它不显示图标和按钮。
为了解决这个问题,我实际上在项目中添加了一个 Resource.resx 文件,并在其中添加了图像。由于 resource.resx 文件是在编译期间添加到 VSIX 文件中的,因此在安装后可以正确显示。
修改后的代码
public System.Drawing.Image Image => Resource.MyImage;
VSIX 安装的资产在 .vsixmanifest 文件中声明。在您的情况下,您已经拥有:
<Assets>
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
然而,第二项应该是不必要的。只有在注册新包时才需要 Pkgdef 文件 - 即从 Microsoft.VisualStudio.Shell.Package 或 Microsoft.VisualStudio.Shell.AsyncPackage 继承的 class (这些用于与您使用的扩展点不同的扩展点)。由于您的 MEF 组件已经注册(这似乎是您唯一需要的),您的 VSIX 应该已经可以正常安装了。
为了更详细地说明这些,安装 VSIX 时,它会查看这些资产,然后根据它们重新配置 VS。
- MefComponent 意味着应该将此程序集添加到 Visual Studio 的 MEF 目录中,然后它将适当地发现任何导出的部件。我没有看到你实际上导出任何东西,所以那里可能缺少一些东西。您可能还需要将
[Export(typeof(ITeamExplorerNavigationItem))]
添加到您的 class(但我不熟悉该功能,所以我不是肯定的)。
- VsPackage 将获取一堆注册属性并将它们转换为注册表项(这实际上是 .pkgdef 文件包含的内容)。安装后,这些将合并到 Visual Studio 的注册表配置单元中。
编辑(回复评论):
如果问题是你的图像未加载,可能是因为你的 VSIX 不包含你的图像,或者因为你没有使用正确的文件路径。默认情况下,所有文件路径都将相对于 devenv.exe 所在的文件夹进行解析。假设您的图像位于您的 DLL 旁边,您可能需要执行如下操作:
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string iconPath = Path.Combine(assemblyFolder, "MyImage.png");
您可以使用 Process Monitor (procmon) 之类的工具来准确查看进程加载失败的路径。 (不知道为什么调试的时候能用,安装的时候不行。)
我正在尝试用 C# 制作一个 VSIX 插件。当我处于开发模式时,该插件工作正常。但是当我尝试安装插件时,即通过双击 VSIX,它不起作用。 我已经阅读了一些文档,有些人说要打包然后进行安装。但是当我将“生成 .pkgdef 文件”选项设置为“真”时,我收到类似“CreatePkgDef:错误:ArgumentException:在此程序集中找不到 Visual Studio 注册属性”的错误。并且程序集应包含程序集 'Microsoft.VisualStudio.Shell.Framework' 版本 '16.0.0.0'
中定义的属性 'Microsoft.VisualStudio.Shell.RegistrationAttribute' 的实例基本上我想部署我的 VSIX。我该怎么做?有人可以帮忙吗? 谢谢。
我遇到了真正的问题。实际上我正在使用 ITeamExplorerNavigationItem2 在团队资源管理器中添加一个按钮。 我正在使用 属性 public System.Drawing.Image 图像来控制按钮图标。
public System.Drawing.Image Image => null // Button comes up without any button icon
public System.Drawing.Image Image => System.Drawing.Image.FromFile("MyImage.png"); // button does not show up in the team explorer
我怀疑的是,在调试期间它正在寻找“MyImage.png”的路径,但是在 运行 时图像没有打包到 VSIX,所以它没有找到.png 路径,随后它不显示图标和按钮。
为了解决这个问题,我实际上在项目中添加了一个 Resource.resx 文件,并在其中添加了图像。由于 resource.resx 文件是在编译期间添加到 VSIX 文件中的,因此在安装后可以正确显示。 修改后的代码
public System.Drawing.Image Image => Resource.MyImage;
VSIX 安装的资产在 .vsixmanifest 文件中声明。在您的情况下,您已经拥有:
<Assets>
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
然而,第二项应该是不必要的。只有在注册新包时才需要 Pkgdef 文件 - 即从 Microsoft.VisualStudio.Shell.Package 或 Microsoft.VisualStudio.Shell.AsyncPackage 继承的 class (这些用于与您使用的扩展点不同的扩展点)。由于您的 MEF 组件已经注册(这似乎是您唯一需要的),您的 VSIX 应该已经可以正常安装了。
为了更详细地说明这些,安装 VSIX 时,它会查看这些资产,然后根据它们重新配置 VS。
- MefComponent 意味着应该将此程序集添加到 Visual Studio 的 MEF 目录中,然后它将适当地发现任何导出的部件。我没有看到你实际上导出任何东西,所以那里可能缺少一些东西。您可能还需要将
[Export(typeof(ITeamExplorerNavigationItem))]
添加到您的 class(但我不熟悉该功能,所以我不是肯定的)。 - VsPackage 将获取一堆注册属性并将它们转换为注册表项(这实际上是 .pkgdef 文件包含的内容)。安装后,这些将合并到 Visual Studio 的注册表配置单元中。
编辑(回复评论): 如果问题是你的图像未加载,可能是因为你的 VSIX 不包含你的图像,或者因为你没有使用正确的文件路径。默认情况下,所有文件路径都将相对于 devenv.exe 所在的文件夹进行解析。假设您的图像位于您的 DLL 旁边,您可能需要执行如下操作:
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string iconPath = Path.Combine(assemblyFolder, "MyImage.png");
您可以使用 Process Monitor (procmon) 之类的工具来准确查看进程加载失败的路径。 (不知道为什么调试的时候能用,安装的时候不行。)