VS.Net插件制作初级教程
作者:东方蜘蛛 2002年5月 | |||
概述: // Insert the current date in my favorite format. // bool InsertDate() { if (null != applicationObject.ActiveDocument) ((TextSelection)applicationObject.ActiveDocument.Selection).Text = DateTime.Now.ToString("dd-MMM-yyyy"); return true; } 现在我们就可以运行它了,按一下F5,我们看到启动了一个新的IDE实例。点击工具——》外接程序管理器,弹出如下窗口。 选择文本编辑插件左边的复选框,点确定以后装载插件。 本程序的运行机理是使用Process来模拟用户的DOS命令,当用户选中项目中的EXE文件以后(由于默认我们无法看到BIN目录下的东西,所以请点一下SHOW ALL FILES选择),此插件侦测到用户选中的是EXE文件以后,会自动从隐藏状态变成显示状态,如左上图,程序自动填充了当前文件的路径信息和命令名称,我们所需要做的只是选择可执行文件而已(程序已经做了筛选),我们也可以通过点击选取路径按钮或者双击路径文本框来选择运行项目以外的程序,点了执行命令以后,RICHTEXT控件里将展示程序的运行结果,这样一晃而过的东西就变成“永恒”啦,呵呵。 来看代码吧,来看关键的执行命令的代码。 private void Start() { Process p = new Process(); StreamWriter sw; StreamReader sr; StreamReader err; ProcessStartInfo psI = new ProcessStartInfo("cmd"); psI.UseShellExecute = false; psI.RedirectStandardInput = true; psI.RedirectStandardOutput = true; psI.RedirectStandardError = true; psI.CreateNoWindow = true; p.StartInfo = psI; sw = p.StandardInput; sr = p.StandardOutput; err = p.StandardError; if (this.txtCommandname.Text != "") { //切换到当前目录 sw.WriteLine("cd "+this.txtPathInfo.Text); sw.WriteLine(this.localdrive); sw.WriteLine(this.txtCommandname.Text); } else //execute default command sw.WriteLine("dir c://"); sw.Close(); this.txtResult.AppendText(sr.ReadToEnd()); this.txtResult.AppendText(err.ReadToEnd()); } public void SetCommandInfo(string strPath) { int endposition = strPath.LastIndexOf("//"); int startposition = strPath.IndexOf("//",0,strPath.Length); string path = strPath.Substring(0,endposition); string filename = strPath.Substring(endposition+1); this.txtPathInfo.Text = path; this.txtCommandname.Text = filename; this.localdrive = strPath.Substring(0,startposition); } 点击执行以后就是执行Start这个函数,关于PROCESS的更详细的信息请看一下MSDN里的帮助,这里我们看到程序利用了CMD作为入口,就象在开始菜单——运行里面打CMD一样,接着程序利用DOS命令切换到当前目录,然后执行程序,最后再是读出程序的执行结果,总而言之,这部分代码比较简单。 另外一个函数是做改变当前程序设置用的。 接下来看我们这次的主体Connect.CS里的东西 public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) { handled = false; if(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault) { if(commandName == "Command.Connect.Command") { if (this.doscommand == null) { this.ShowWindow(); } else { this.window.Activate(); } handled = true; return; } } } 这个是主体程序,可以看到主要是根据当前控件是否已经实例化来决定是否执行ShowWindow函数,如果已经是的话,将直接调用装载控件的窗体。这里的doscommand就是刚刚我们创建的控件的一个引用。 private void ShowWindow() { object objTemp = null; try { string guid = "{C7520611-4791-41a9-9AE8-178F78844C2E}"; window = applicationObject.Windows.CreateToolWindow(addInInstance,"EastSpider.Command.DOSCommand","EastSpider.Command.DOSCommand",guid,ref objTemp); if (window.IsFloating) { window.Height = 700; window.Width = 800; } AddToMainWindow(window); window.Visible = true; selectionEvents = (EnvDTE.SelectionEvents)applicationObject.Events.SelectionEvents; selectionEvents.OnChange += new EnvDTE._dispSelectionEvents_OnChangeEventHandler(this.SelectionOnChange); this.doscommand = (EastSpider.Command.DOSCommand)objTemp; } catch { } } private void AddToMainWindow(Window win) { Window mainWindow = applicationObject.MainWindow; Windows windows = applicationObject.Windows; LinkedWindows lw = mainWindow.LinkedWindows; if ( lw != null ) { if ( win.AutoHides != true) lw.Add(win); } } 这两段程序建立了装载控件的窗体,并自动“靠边隐藏”,:) private bool IsExeFileSelected() EnvDTE.SelectedItem selectedItem = selectedItems.Item(1); if ( selectedItem == null ) return false; EnvDTE.ProjectItem projectItem = selectedItem.ProjectItem; if ( projectItem == null ) return false; string fullName = projectItem.get_FileNames(1); string ext = System.IO.Path.GetExtension(fullName); if (string.Compare(ext, ".exe", true) != 0) return false; else return true; } private void SelectionOnChange() { if ( ( applicationObject.SelectedItems.Count == 1 ) && IsExeFileSelected()) { window.Visible = true; doscommand.SetCommandInfo(applicationObject.SelectedItems.Item(1).ProjectItem.get_FileNames(1)); } } 这两段代码是判断当前是否选择了唯一的可执行文件,如果是,把参数传递给控件类里用于改变当前默认设置,这样,就做到了用户只需选择文件,程序就可自动做出反应。 注意:出于程序的需要(Connect.cs里创建窗体的时候),我给控件类指定了ProgId 和 Guid,如下: [ProgId("EastSpider.Command.DOSCommand"),Guid("C7520611-4791-41a9-9AE8-178F78844C2E")] public class DOSCommand : System.Windows.Forms.UserControl ……. 将命名空间与类型名组合在一起可以为类自动生成 ProgId。然而,这可能产生无效的 ProgId,具体的信息请参考一下MSDN吧。 由于代码比较多,这里不能一一全部奉上了,以上的代码已经完全能实现我所说的功能了,剩下的一些零碎的东西我相信大家自己补充一下肯定不成问题,关于公共环境对象模型(EnvDTE 类型库)等相关的信息,请大家还是参考一下MSDN里面的东西,由于大部分代码都是自动生成的,我们所要的只是引用而已,我也不介绍了。我会在适当的时间发布整个工程,请关注http://www.dev-club.com/club/bbs/main.asp?boardid=115,关于工程的实例,请到这里下载ftp://devclub:devclub@202.106.155.102/,关于插件的更多资源,请参考这里http://msdn.microsoft.com/vstudio/downloads/automation.asp,希望这两个实例能对你有些帮助,我是东方蜘蛛。 |