VS2013使用VS2008的联合编译进行工程编译
公司开发C++是使用vs2008,编译的时候使用联合编译IncreBuild进行编译;在vs2008中使用visual assistx,如果代码太长,滚动的时候偶尔会出现页面乱码,而且有时候虚函数互相定位也有问题,没有vs2013使用方便,但是在vs2013中又不能直接编译,所有寻思做个插件解决编译问题;
因为工程文件都是使用vc9生成的,所有使用vs2013打开时,会自动进行工程升级,升级完成后,vc9和vs2013的工程会同时存在,如果想在vs2013中调用vs2008的编译器进行编译,可以通过联合编译调用vs2008的工程文件编译;
1、创建vs2013的插件工程;
2、在connect.cs中,修改函数OnConnection,在末尾增加代码,用来增加菜单
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 }
3、修改函数QueryStatus,用来显示菜单
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 }
4、执行的时候,根据获得到的工程文件,解析路径,然后编写一个使用联合编译的脚本就行了
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 }