zoukankan      html  css  js  c++  java
  • csproj项目工程文件的脚本/动态链接库设置

    最近整理到很久之前项目中的一段偷懒处理,主要针对新加入U3D项目的插件、脚本、动态链接库等没有正常设置,导致在使用VS打开时报错,也没办法使用其自动补齐、智能提示等偷懒功能,甚至连相关定义都看不到,全局搜索时甚至搜索不到的情况。

    主要原理是根据文件所在路径判断其编译关系,是放在4种csproj工程文件的具体哪一个。其他废话不多说了,直接上代码:

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    
    public class CSProjTools 
    {
    	[MenuItem("Assets/Add2CSProj")]
    	static void Add2CSProj()
    	{
    		//判断路径是否包含Editor、Plugins、Standard Assets
    		//根据包含情况,加载读取项目目录下的.csproj文件
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);
    		if(Directory.Exists(tSelectPath))	//选中文件夹,须递归遍历文件
    		{
    			var tFileArr = Directory.GetFiles(tSelectPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".cs") || s.EndsWith(".dll"));
    			foreach(var filepath in tFileArr)
    			{
    				string tCSProjFilePath = tProjPath + tProjName + getCSProjFileName(filepath);
    				insertCSProjFile(tCSProjFilePath, filepath);
    			}
    		}
    		else //if(File.Exists(tSelectPath))	//选中的是文件
    		{
    			tSelectPath = tSelectPath.Replace(tProjPath, "");
    			string tCSProjFilePath = tProjPath + tProjName + getCSProjFileName(tSelectPath);
    			insertCSProjFile(tCSProjFilePath, tSelectPath);
    		}
    	}
    	static string getCSProjFileName(string _filePath)
    	{
    		_filePath = _filePath.Replace("\", "/");
    		if(_filePath.Contains("/Editor/"))
    		{
    			if(_filePath.Contains("Assets/Plugins/") || _filePath.Contains("Assets/Standard Assets/"))
    			{
    				return ".CSharp.Editor.Plugins.csproj";
    			}
    			else
    			{
    				return ".CSharp.Editor.csproj";
    			}
    		}
    		else
    		{
    			if(_filePath.Contains("Assets/Plugins/") || _filePath.Contains("Assets/Standard Assets/"))
    			{
    				return ".CSharp.Plugins.csproj";
    			}
    			else
    			{
    				return ".CSharp.csproj";
    			}
    		}
    	}
    	static void insertCSProjFile(string _csprojFilePath, string _filePath)
    	{
    		XmlDocument tXmlDoc = new XmlDocument();
    		tXmlDoc.Load(_csprojFilePath);
    
    		string tNameSpace = "http://schemas.microsoft.com/developer/msbuild/2003";
    		XmlNamespaceManager tNameSpaceMgr = new XmlNamespaceManager(tXmlDoc.NameTable);
    		tNameSpaceMgr.AddNamespace("ns", tNameSpace);	//不加入namespace会找不到
    		XmlNode tRootNode = tXmlDoc.SelectSingleNode("ns:Project", tNameSpaceMgr);
    		XmlNodeList tGroupLst = tRootNode.SelectNodes("ns:ItemGroup", tNameSpaceMgr);
    		//XmlNodeList tGroupLst = tXmlDoc.SelectNodes("/ns:Project/ns:ItemGroup", tNameSpaceMgr);
    
    		foreach(XmlNode item in tGroupLst)
    		{
    			XmlElement tGroupElem = (XmlElement)item;
    
    			//暂不考虑不包含子节点的情况
    			if(_filePath.EndsWith(".dll") && item.FirstChild.Name == "Reference")		//dll动态链接库
    			{
    				var tArr = _filePath.Split('/');
    				string tValue = tArr[tArr.Length - 1].Replace(".dll", "");
    				foreach(XmlNode child in item.ChildNodes)
    				{
    					foreach(XmlAttribute attr in child.Attributes)
    					{
    						if(attr.Name == "Include" && attr.Value == tValue)
    						{
    							return;
    						}
    					}
    				}
    				XmlElement tChild = (XmlElement)item.FirstChild.CloneNode(true);
    				tChild.SetAttribute("Include", tValue);
    
    				XmlElement tSubChild = tXmlDoc.CreateElement("HintPath", tNameSpace);
    				tSubChild.InnerText = _filePath.Replace("/", "\");
    
    				tChild.AppendChild(tSubChild);
    				item.AppendChild(tChild);
    				break;
    			}
    			else if((_filePath.EndsWith(".cs") && item.FirstChild.Name == "Compile") || item.FirstChild.Name == "None")	//CS脚本或资源
    			{
    				foreach(XmlNode child in item.ChildNodes)
    				{
    					foreach(XmlAttribute attr in child.Attributes)
    					{
    						if(attr.Name == "Include" && attr.Value == _filePath)
    						{
    							return;
    						}
    					}
    				}
    				XmlElement tChild = (XmlElement)item.FirstChild.CloneNode(true);
    				//XmlElement tChild = tXmlDoc.CreateElement(item.FirstChild.Name, tNameSpace);
    				tChild.SetAttribute("Include", _filePath.Replace("/", "\"));
    				item.AppendChild(tChild);
    				break;
    			}
    		}
    		tXmlDoc.Save(_csprojFilePath);
    	}
    }
    

      美中不足之处是每次都需要重新加载工程,不如使用右键的方式逐个加入文件和引用来的方便。后来也有考虑使用VSLangProj.dll结合EnvDTE一起使用来进一步完善,不过当时够用就罢手了。再后来也就一直没有时间重新拿起。

    //todo:考虑将同一dll加入到多个csproj的情况
    	[MenuItem("Assets/Add2ExtraCSProj/CS")]
    	static void Add2CSProjCS()
    	{
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);	//暂不考虑选中多文件的情况
    		tSelectPath = tSelectPath.Replace(tProjPath, "");
    		string tCSProjFilePath = tProjPath + tProjName + ".CSharp.csproj";
    		insertCSProjFile(tCSProjFilePath, tSelectPath);
    	}
    	[MenuItem("Assets/Add2ExtraCSProj/CSPlugin")]
    	static void Add2CSProjCSPlugin()
    	{
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);	//暂不考虑选中多文件的情况
    		tSelectPath = tSelectPath.Replace(tProjPath, "");
    		string tCSProjFilePath = tProjPath + tProjName + ".CSharp.Plugins.csproj";
    		insertCSProjFile(tCSProjFilePath, tSelectPath);
    	}
    	[MenuItem("Assets/Add2ExtraCSProj/CSEditor")]
    	static void Add2CSProjCSEditor()
    	{
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);	//暂不考虑选中多文件的情况
    		tSelectPath = tSelectPath.Replace(tProjPath, "");
    		string tCSProjFilePath = tProjPath + tProjName + ".CSharp.Editor.csproj";
    		insertCSProjFile(tCSProjFilePath, tSelectPath);
    	}
    	[MenuItem("Assets/Add2ExtraCSProj/CSEditorPlugin")]
    	static void Add2CSProjCSEditorPlugin()
    	{
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);	//暂不考虑选中多文件的情况
    		tSelectPath = tSelectPath.Replace(tProjPath, "");
    		string tCSProjFilePath = tProjPath + tProjName + ".CSharp.Editor.Plugins.csproj";
    		insertCSProjFile(tCSProjFilePath, tSelectPath);
    	}
    
    
    
    	[MenuItem("Assets/Add2CSProj")]
    	static void Add2CSProj()
    	{
    		//判断路径是否包含Editor、Plugins、Standard Assets等
    		//根据包含情况,加载读取项目目录下的.csproj文件
    		if(Selection.activeObject == null)
    		{
    			return;
    		}
    		string tProjPath = Application.dataPath.Replace("Assets", "");
    		var tArr = tProjPath.Split('/');
    		string tProjName = tArr[tArr.Length - 2];
    		string tSelectPath = tProjPath + AssetDatabase.GetAssetPath(Selection.activeObject);	//暂不考虑选中多文件的情况
    		if(Directory.Exists(tSelectPath))	//选中文件夹,须递归遍历文件
    		{
    			var tFileArr = Directory.GetFiles(tSelectPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".cs") || s.EndsWith(".dll"));
    			foreach(var filepath in tFileArr)
    			{
    				string tCSProjFilePath = tProjPath + tProjName + getCSProjFileName(filepath);
    				insertCSProjFile(tCSProjFilePath, filepath, false);
    			}
    			//统一存储,防止IO效率及冲突
    			foreach(var kv in xmlDocCacheMap)
    			{
    				if(insertCountMap.ContainsKey(kv.Key) && insertCountMap[kv.Key] > 0)
    				{
    					kv.Value.Save(kv.Key);
    				}
    			}
    			xmlDocCacheMap.Clear();
    			xmlNodeLstCacheMap.Clear();
    		}
    		else //if(File.Exists(tSelectPath))	//选中的是文件
    		{
    			tSelectPath = tSelectPath.Replace(tProjPath, "");
    			string tCSProjFilePath = tProjPath + tProjName + getCSProjFileName(tSelectPath);
    			insertCSProjFile(tCSProjFilePath, tSelectPath);
    		}
    		string tTipStr = "Add2CSProj Finished: 
    ";
    		foreach(var kv in insertCountMap)
    		{
    			tTipStr += "	" + kv.Key + ": " + kv.Value;
    		}
    		insertCountMap.Clear();
    		Debug.LogError(tTipStr);
    	}
    	static string getCSProjFileName(string _filePath)
    	{
    		_filePath = _filePath.Replace("\", "/");
    		if(_filePath.Contains("/Editor/"))
    		{
    			if(_filePath.Contains("Assets/Plugins/") || _filePath.Contains("Assets/Standard Assets/"))
    			{
    				return ".CSharp.Editor.Plugins.csproj";
    			}
    			else
    			{
    				return ".CSharp.Editor.csproj";
    			}
    		}
    		else
    		{
    			if(_filePath.Contains("Assets/Plugins/") || _filePath.Contains("Assets/Standard Assets/"))
    			{
    				return ".CSharp.Plugins.csproj";
    			}
    			else
    			{
    				return ".CSharp.csproj";
    			}
    		}
    	}
    
    	static string xmlNameSpace = "http://schemas.microsoft.com/developer/msbuild/2003";
    	static IDictionary<string, XmlDocument> xmlDocCacheMap = new Dictionary<string, XmlDocument>();
    	static IDictionary<string, XmlNodeList> xmlNodeLstCacheMap = new Dictionary<string, XmlNodeList>();
    	static IDictionary<string, int> insertCountMap = new Dictionary<string, int>();
    	static void insertCSProjFile(string _csprojFilePath, string _filePath, bool _syncSave = true)
    	{
    		if(_filePath.StartsWith(Application.dataPath))
    		{
    			_filePath = _filePath.Replace(Application.dataPath, "Assets");
    		}
    		//Debug.LogError(_csprojFilePath + "	" + _filePath);
    
    		XmlDocument tXmlDoc = null;
    		XmlNodeList tGroupLst = null;
    		if(xmlDocCacheMap.ContainsKey(_csprojFilePath))
    		{
    			tXmlDoc = xmlDocCacheMap[_csprojFilePath];
    			tGroupLst = xmlNodeLstCacheMap[_csprojFilePath];
    		}
    		else
    		{
    			tXmlDoc = new XmlDocument();
    			tXmlDoc.Load(_csprojFilePath);
    			
    			XmlNamespaceManager tNameSpaceMgr = new XmlNamespaceManager(tXmlDoc.NameTable);
    			tNameSpaceMgr.AddNamespace("ns", xmlNameSpace);	//不加入namespace会找不到
    			XmlNode tRootNode = tXmlDoc.SelectSingleNode("ns:Project", tNameSpaceMgr);
    			tGroupLst = tRootNode.SelectNodes("ns:ItemGroup", tNameSpaceMgr);
    			//tGroupLst = tXmlDoc.SelectNodes("/ns:Project/ns:ItemGroup", tNameSpaceMgr);
    
    			xmlDocCacheMap[_csprojFilePath] = tXmlDoc;
    			xmlNodeLstCacheMap[_csprojFilePath] = tGroupLst;
    		}
    
    		//Debug.LogError(_filePath);
    		_filePath = _filePath.Replace("/", "\");
    		foreach(XmlNode item in tGroupLst)
    		{
    			XmlElement tGroupElem = (XmlElement)item;
    			//Debug.LogError(item.FirstChild.Name);
    
    			//暂不考虑不包含子节点的情况
    			if(_filePath.EndsWith(".dll") && item.FirstChild.Name == "Reference")		//dll动态链接库
    			{
    				var tArr = _filePath.Split('\');
    				string tValue = tArr[tArr.Length - 1].Replace(".dll", "");
    				foreach(XmlNode child in item.ChildNodes)
    				{
    					foreach(XmlAttribute attr in child.Attributes)
    					{
    						if(attr.Name == "Include" && attr.Value == tValue)
    						{
    							return;
    						}
    					}
    				}
    				XmlElement tChild = (XmlElement)item.FirstChild.CloneNode(true);
    				tChild.SetAttribute("Include", tValue);
    
    				XmlElement tSubChild = tXmlDoc.CreateElement("HintPath", xmlNameSpace);
    				tSubChild.InnerText = _filePath;
    
    				tChild.AppendChild(tSubChild);
    				item.AppendChild(tChild);
    				if(!insertCountMap.ContainsKey(_csprojFilePath))
    				{
    					insertCountMap[_csprojFilePath] = 0;
    				}
    				insertCountMap[_csprojFilePath]++;
    				break;
    			}
    			else if((_filePath.EndsWith(".cs") && item.FirstChild.Name == "Compile") || item.FirstChild.Name == "None")	//CS脚本或资源
    			{
    				//Debug.LogError(item.FirstChild.InnerText + "
    " + item.FirstChild.Value);
    				//foreach(XmlAttribute attr in item.FirstChild.Attributes)
    				//{
    				//	Debug.LogError(attr.Name + "	" + attr.Value);
    				//}
    				foreach(XmlNode child in item.ChildNodes)
    				{
    					foreach(XmlAttribute attr in child.Attributes)
    					{
    						if(attr.Name == "Include" && attr.Value == _filePath)
    						{
    							return;
    						}
    					}
    				}
    				XmlElement tChild = (XmlElement)item.FirstChild.CloneNode(true);
    				//XmlElement tChild = tXmlDoc.CreateElement(item.FirstChild.Name, tNameSpace);
    				tChild.SetAttribute("Include", _filePath);
    				item.AppendChild(tChild);
    				if(!insertCountMap.ContainsKey(_csprojFilePath))
    				{
    					insertCountMap[_csprojFilePath] = 0;
    				}
    				insertCountMap[_csprojFilePath]++;
    				break;
    			}
    		}
    		if(_syncSave)
    		{
    			tXmlDoc.Save(_csprojFilePath);    //todo:try-catch,防止IO异常
    
    			xmlDocCacheMap.Remove(_csprojFilePath);
    			xmlNodeLstCacheMap.Remove(_csprojFilePath);
    		}
    	}
    

      

  • 相关阅读:
    JS判断输入是否为整数和数字的正则表达式
    c#字符串转换为日期,支持任意字符串
    清除sql server 登录的时候记住的账户
    关于sql 的convert 格式设置
    ArcObjects SDK(AE)10.1在vs2012安装的方法
    解决ArcGIS Engine AE 读取shapefile中文属性乱码的一条偏方
    skyline TerraBuilder 制作MPT方法与技巧(2)
    skyline TerraBuilder 制作MPT方法与技巧(1)
    Makefile之文件搜索
    Makefile学习之通配符和自动变量($@、$<、$^)
  • 原文地址:https://www.cnblogs.com/wayland/p/11139710.html
Copyright © 2011-2022 走看看