因为我们公司的一个项目是通过壳项目引用实际项目进行调试,当修改实际项目页面时,不能即时保存到壳项目中,使用专用的同步工具感觉有点杀鸡用牛刀

VS下又没有类似插件(只找到一个设置单个文件保存后执行指定命令的插件,不能根据扩展名自动处理),参考网上开源项目,从新写了一个插件

https://marketplace.visualstudio.com/items?itemName=zgj.CopyOnSave

在VisualStudio里搜索 CopyOnSave 即可找到

1、核心代码如下

 public int OnAfterSave(uint docCookie)
        {
            try
            {
                ThreadHelper.ThrowIfNotOnUIThread();
                var document = FindDocument(docCookie);

                if (document == null)
                    return VSConstants.S_OK;


                string solutionPath = Directory.GetParent(document.DTE.Solution.FullName).FullName;

                List<string> fileFilter = new List<string>();
                List<string> destDirectory = new List<string>();
                List<string> fromDirectory = new List<string>();
                string cfgFilePath = solutionPath + "\\SaveCopy.cfg";
                if (!File.Exists(cfgFilePath)) return VSConstants.S_OK;
                // 创建一个 StreamReader 的实例来读取文件 
                using (StreamReader sr = new StreamReader(cfgFilePath))
                {
                    string line;

                    // 从文件读取并显示行,直到文件的末尾 
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.StartsWith("ExtensionFilter:"))
                        {
                            fileFilter.AddRange(line.Replace("ExtensionFilter:", "").Replace(@"""", "").Split(',').ToList());
                        }
                        if (line.StartsWith("CopyToDirectory:"))
                        {
                            destDirectory.AddRange(line.Replace("CopyToDirectory:", "").Replace(@"""", "").Split(',').ToList());
                        }
                        if (line.StartsWith("FromDirectory:"))
                        {
                            fromDirectory.AddRange(line.Replace("FromDirectory:", "").Replace(@"""", "").Split(',').ToList());
                        }
                    }
                }
                
                if (fileFilter.Count == 0 || destDirectory.Count == 0)
                {
                    return VSConstants.S_OK;

                }
                string srcFile = document.FullName;
                bool bNeedCopy = false;
                foreach (var item in fileFilter)
                {
                    if (srcFile.EndsWith(item))
                    {
                        bNeedCopy = true;
                    }
                }
                if (bNeedCopy)
                {

                    if (fromDirectory.Count > 0)
                    {
                        foreach (string projectPath in fromDirectory)
                        {
                            string projectFolder = projectPath;
                            if (srcFile.StartsWith(projectFolder))
                            {
                                string relativePath = srcFile.Replace(projectFolder, "").TrimStart('\\');

                                foreach (string destPath in destDirectory)
                                {
                                    string destFile = MyPath.Combine(destPath,relativePath);
                                    if (destFile == srcFile) continue;//目标目录中修改自己不拷贝
                                    string destFileDirectory = Path.GetDirectoryName(destFile);
                                    if (!Directory.Exists(destFileDirectory))
                                    {
                                        Directory.CreateDirectory(destFileDirectory);
                                    }
                                    File.Copy(srcFile, destFile, true);
                                }

                            }
                        }
                    }
                    else
                    {
                        foreach (Project projectItem in document.DTE.Solution.Projects)
                        {
                            if (projectItem.FullName == "") continue;
                            string projectFolder = Directory.GetParent(projectItem.FullName).FullName + "\\";
                            if (srcFile.StartsWith(projectFolder))
                            {
                                string relativePath = srcFile.Replace(projectFolder, "").TrimStart('\\'); ;

                                foreach (string destPath in destDirectory)
                                {
                                    string destFile = MyPath.Combine(destPath, relativePath);
                                    if (destFile == srcFile) continue;//目标目录中修改自己不拷贝
                                    string destFileDirectory = Path.GetDirectoryName(destFile);
                                    if (!Directory.Exists(destFileDirectory))
                                    {
                                        Directory.CreateDirectory(destFileDirectory);
                                    }
                                    File.Copy(srcFile, destFile, true);
                                }

                            }

                        }
                    }



                }
            }
            catch (System.Exception ex)
            {

                return VSConstants.S_OK;
            }
            
            
            return VSConstants.S_OK;
        }

  

2、插件使用

因为每个项目solution需要拷贝的文件可能不一样,所有使用单独配置文件放到项目目录下根目录下增加一个配置文件SaveCopy.cfg,内容如下

ExtensionFilter:".js,.html"
CopyToDirectory:"I:\xxxxx"
FromDirectory:"I:\xxxxx"

FromDirectory必须是子项目的根路径,也可以忽略不写,具体文档看插件首页介绍。

现在修改保存项目中的html或者js文件,就会自动在目标路径下生成一份同样的代码。

通过上一篇

VisualStudio下支持多个git项目的git插件  

和本篇,终于可以摆脱目前我们公司目前的项目中使用Rider比VS还方便的困境啦,毕竟vs的即时调试之类的独有的特性,还有大家的习惯是不容忽视的!