VS插件开发生成一个简易的WPF资源URL
VS插件开发生成一个简易的WPF资源URL
01. 前言
因为 WPF 资源 URL 非常难写,虽然我会但是每次写多少有点掉头发,为此如何制作一个对应的工具就显得很有必要了。
你可能需要先看一下之前的那篇,它介绍了如何从VS插件获得解决方案资源管理器的选中项。
02. 代码
我们的项目结构是这个样子的:

我们选中的是 Test/Class1.cs 这个文件,我们希望能够输出对应的相对路径。
using EnvDTE;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace VCmdTest
{
internal class Program
{
static void Main(string[] args)
{
var DTE = Marshal.GetActiveObject("VisualStudio.DTE") as EnvDTE80.DTE2;
var toolWindow = DTE.ToolWindows;
var solutionExplorer = toolWindow.SolutionExplorer;
var selectedItems = (solutionExplorer.SelectedItems as IEnumerable).OfType<UIHierarchyItem>().Select(i=>i.Object).OfType<ProjectItem>();
var selectedItem = selectedItems.FirstOrDefault();
if (selectedItem == null) return;
var project = selectedItem.ContainingProject;
var projectPath = project.FullName;
var projectName = Path.GetFileNameWithoutExtension(projectPath);
var projectDirPath = Path.GetDirectoryName(projectPath);
var filePath = selectedItem.FileNames[0];
var partPath = filePath.Substring(projectDirPath.Length);
Console.WriteLine(partPath);
Console.ReadKey();
//System.Diagnostics.Process.Start(Environment.GetFolderPath( Environment.SpecialFolder.Desktop));
}
}
}
结果如下:

03. 更进阶的改造
我们要完成对 WPF 资源 URL 的设置,这个可以改造成这个样子:
using EnvDTE;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace VCmdTest
{
internal class Program
{
[STAThread]
static void Main(string[] args)
{
var DTE = Marshal.GetActiveObject("VisualStudio.DTE") as EnvDTE80.DTE2;
var toolWindow = DTE.ToolWindows;
var solutionExplorer = toolWindow.SolutionExplorer;
var selectedItems = (solutionExplorer.SelectedItems as IEnumerable).OfType<UIHierarchyItem>().Select(i=>i.Object).OfType<ProjectItem>();
var selectedItem = selectedItems.FirstOrDefault();
if (selectedItem == null) return;
var project = selectedItem.ContainingProject;
var projectPath = project.FullName;
var projectName = Path.GetFileNameWithoutExtension(projectPath);
var projectDirPath = Path.GetDirectoryName(projectPath);
var filePath = selectedItem.FileNames[0];
var partPath = filePath.Substring(projectDirPath.Length);
var url = GetWPFURL(projectName, partPath);
Console.WriteLine(url);
Clipboard.SetText(url);
Console.ReadKey();
//System.Diagnostics.Process.Start(Environment.GetFolderPath( Environment.SpecialFolder.Desktop));
}
static string GetWPFURL(string assemblyName, string relPath)
{
var relPathFixed = relPath.Replace('\\', '/');
return $"pack://application:,,,/{assemblyName};component{relPathFixed}";
}
}
}
04. VCmd 化
标题:创建 WPF URL
using EnvDTE;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Windows.Forms;
public class C : VisualCommanderExt.ICommand
{
public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
var toolWindow = DTE.ToolWindows;
var solutionExplorer = toolWindow.SolutionExplorer;
var selectedItems = (solutionExplorer.SelectedItems as IEnumerable).OfType<UIHierarchyItem>().Select(i=>i.Object).OfType<ProjectItem>();
var selectedItem = selectedItems.FirstOrDefault();
if (selectedItem == null) return;
var project = selectedItem.ContainingProject;
var projectPath = project.FullName;
var projectName = Path.GetFileNameWithoutExtension(projectPath);
var projectDirPath = Path.GetDirectoryName(projectPath);
var filePath = selectedItem.FileNames[0];
var partPath = filePath.Substring(projectDirPath.Length);
var url = GetWPFURL(projectName, partPath);
//Console.WriteLine(url);
Clipboard.SetText(url);
}
string GetWPFURL(string assemblyName, string relPath)
{
var relPathFixed = relPath.Replace('\\', '/');
return "pack://application:,,,/"+assemblyName+";component"+relPathFixed;
}
}
05. 将 VCmd 命令加入到解决方案资源管理器的右键上下文菜单中
1. 打开自定义菜单

2. 在命令-上下文菜单中配置

因为我的 VCmd 命令是在第三个,所以说对应的命令就是 Command03
3. 效果如下


浙公网安备 33010602011771号