public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) { handled = false; if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) { if(commandName == "MyAddin1.Connect.MyAddin1") { // 實現自訂的邏輯 TestCSharpCompiler(); handled = true; return; } } } private void TestCSharpCompiler() { // 擷取當前Visual Studio的解決方案,如果Visual Studio還沒有任何方案 // 就是預設的空解決方案 var solution = (Solution2)_applicationObject.Solution; // 建立一個新的“C# 命令列程式(C# Console Application)”工程 var csTemplatePath = solution.GetProjectTemplate("ConsoleApplication.zip", "CSharp"); // 工程名(Test Project)以及儲存工程的檔案夾路徑(d:\temp\test) solution.AddFromTemplate(csTemplatePath, @"d:\temp\test", "Test Project", false); var project = solution.Projects.Item(1); // 將已有的檔案(d:\temp\test.cs)添加到新建立的工程中 project.ProjectItems.AddFromFileCopy(@"d:\temp\test.cs"); // 啟用編譯器 var host = new IDECompilerHost(); var compiler = host.CreateCompiler(project); SourceFile source = null; // 工程裡一般都有很多檔案,找到感興趣的源檔案 // 因為那個檔案的抽象文法樹是我要的東西 foreach (var file in compiler.SourceFiles) { if (string.Compare(file.Key.Value, @"d:\temp\test\test.cs", StringComparison.InvariantCultureIgnoreCase) == 0) { source = file.Value; break; } } // 擷取文法樹的根節點,一般就是源檔案最外層的命名空間 var tree = source.GetParseTree(); IDECompilation compilation = (IDECompilation)compiler.GetCompilation(); // 在文法樹裡擷取第一個命名空間的節點 compilation.CompileTypeOrNamespace(tree.RootNode); var node = tree.RootNode as NamespaceDeclarationNode; // 擷取命名空間節點裡面的類定義、或者子命名空間、或者其它 // 可以定義在命名空間裡面的元素的節點 foreach (var child in node.NamespaceMemberDeclarations.Root.Children) { if (child is BinaryExpressionNode) { var bnode = child as BinaryExpressionNode; var left = bnode.Left as ClassDeclarationNode; var right = bnode.Right as ClassDeclarationNode; Trace.WriteLine(left.Identifier.Name.Text); Trace.WriteLine(right.Identifier.Name.Text); } else { Trace.WriteLine(child.AsName().Name.Text); } } } |