公司開發C++是使用vs2008,編譯的時候使用聯合編譯IncreBuild進行編譯;在vs2008中使用visual assistx,若是代碼太長,滾動的時候偶爾會出現頁面亂碼,並且有時候虛函數互相定位也有問題,沒有vs2013使用方便,可是在vs2013中又不能直接編譯,全部尋思作個插件解決編譯問題;node
由於工程文件都是使用vc9生成的,全部使用vs2013打開時,會自動進行工程升級,升級完成後,vc9和vs2013的工程會同時存在,若是想在vs2013中調用vs2008的編譯器進行編譯,能夠經過聯合編譯調用vs2008的工程文件編譯;app
一、建立vs2013的插件工程;函數
二、在connect.cs中,修改函數OnConnection,在末尾增長代碼,用來增長菜單ui
1 try 2 { 3 //Add a command to the Commands collection: 4 Command command = commands.AddNamedCommand2(_addInInstance, "MyAddin1", "MyAddin1", "Executes the command for MyAddin1", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); 5 6 //Add a control for the command to the tools menu: 7 if((command != null) && (toolsPopup != null)) 8 { 9 command.AddControl(toolsPopup.CommandBar, 1); 10 } 11 CommandBar slnCommandBar = GetCommandBarByName("Project"); 12 // Add a new command 13 AddNamedCommand2(slnCommandBar, "Build", 14 "Build By IncreBuild", "Build By IncreBuild", false, 0, 1); 15 } 16 catch(System.ArgumentException) 17 { 18 //If we are here, then the exception is probably because a command with that name 19 // already exists. If so there is no need to recreate the command and we can 20 // safely ignore the exception. 21 }
三、修改函數QueryStatus,用來顯示菜單spa
1 public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText) 2 { 3 if(neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone) 4 { 5 if(commandName == "MyAddin1.Connect.MyAddin1") 6 { 7 status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported|vsCommandStatus.vsCommandStatusEnabled; 8 return; 9 } 10 if (commandName == "MyAddin1.Connect.Build") 11 { 12 status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; 13 return; 14 } 15 } 16 }
四、執行的時候,根據得到到的工程文件,解析路徑,而後編寫一個使用聯合編譯的腳本就好了插件
1 public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) 2 { 3 handled = false; 4 if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) 5 { 6 if(commandName == "MyAddin1.Connect.MyAddin1") 7 { 8 handled = true; 9 return; 10 } 11 else if (commandName == "MyAddin1.Connect.Build") 12 { 13 try 14 { 15 SelectedItems items = _applicationObject.SelectedItems; 16 System.Array projs = items.DTE.ActiveSolutionProjects as System.Array; 17 string projectname = null; 18 foreach (Project item in projs) 19 { 20 projectname = item.UniqueName; 21 } 22 if (null != projectname) 23 { 24 BuildProject(projectname); 25 } 26 } 27 catch(Exception e) 28 { 29 30 } 31 handled = true; 32 return; 33 } 34 } 35 } 36 37 private void BuildProject(string Proj) 38 { 39 if(!File.Exists(Proj)) 40 { 41 return; 42 } 43 if(!Proj.Contains("vcxproj")) 44 { 45 return; 46 } 47 string oldprj = Proj.Replace("vcxproj", "vcproj"); 48 if(!File.Exists(oldprj)) 49 { 50 return; 51 } 52 XmlDocument xdoc = new XmlDocument(); 53 xdoc.Load(oldprj); 54 XmlElement root=xdoc.SelectSingleNode("VisualStudioProject") as XmlElement; 55 if(root.GetAttribute("ProjectType") != "Visual C++" || 56 root.GetAttribute("Version") != "9.00") 57 { 58 return; 59 } 60 string projname=root.GetAttribute("Name"); 61 List<string> lstconfig = new List<string>(); 62 XmlNodeList lstconfignode = xdoc.SelectNodes("//VisualStudioProject/Configurations/Configuration"); 63 foreach(XmlElement item in lstconfignode) 64 { 65 lstconfig.Add(item.GetAttribute("Name")); 66 } 67 if(lstconfig.Count<=0) 68 { 69 return; 70 } 71 72 DirectoryInfo dir = Directory.GetParent(oldprj); 73 string batfile = dir.ToString() +"\\"+ projname + ".bat"; 74 StreamWriter sw = new StreamWriter(batfile); 75 sw.Write("buildconsole "); 76 sw.Write(oldprj); 77 sw.Write(" /prj=\""); 78 sw.Write(projname); 79 sw.Write("\" /build /OpenMonitor /cfg=\""); 80 sw.Write(lstconfig[0]); 81 sw.Write("\"\r\n"); 82 sw.Flush(); 83 sw.Close(); 84 85 86 87 System.Threading.Thread t = new System.Threading.Thread(new ThreadStart(() => { 88 ProcessStartInfo info = new ProcessStartInfo(batfile); 89 info.CreateNoWindow = true; 90 info.RedirectStandardOutput = false; 91 info.RedirectStandardInput = false; 92 info.UseShellExecute = true; 93 System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); 94 p.WaitForExit(); 95 })); 96 t.Start(); 97 98 99 }