Developing Visual Studio .NET Macros and Add-Ins phần 10 docx

42 329 0
Developing Visual Studio .NET Macros and Add-Ins phần 10 docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

similar to the Macro Explorer that lists scripts in other languages, enabling you to double-click the scripts in this window to run them. The add-in I describe here does just that. It has a tool window containing a treeview control that lists the scripts in a given directory. If you double-click the script, the script runs. Like many of the previous add-ins, this one uses the VSUserControlHost that I described in “Using the Form Designer with a Tool Window” in Chapter 7. And as for the other add-ins, be sure to add a COM reference to the VSUserControlHost 1.0 Type Library. Here’s the Connect module for the add-in: Imports Microsoft.Office.Core imports Extensibility imports System.Runtime.InteropServices Imports EnvDTE <GuidAttribute(“F3D6C34F-CCDB-4D03-94D3-C9E5A15A9491”), _ ProgIdAttribute(“ScriptExplorer.Connect”)> _ Public Class Connect Implements Extensibility.IDTExtensibility2 Implements IDTCommandTarget ‘ Note: I changed applicationObject to public shared! Public Shared applicationObject As EnvDTE.DTE Dim addInInstance As EnvDTE.AddIn Private doc As VSUserControlHostLib.IVSUserControlHostCtl = Nothing Private toolwin As Window = Nothing Public Sub OnBeginShutdown(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnBeginShutdown End Sub Public Sub OnAddInsUpdate(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnAddInsUpdate End Sub Public Sub OnStartupComplete(ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnStartupComplete End Sub Public Sub OnDisconnection(ByVal RemoveMode As _ Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnDisconnection End Sub Public Sub OnConnection(ByVal application As Object, _ ByVal connectMode As Extensibility.ext_ConnectMode, _ ByVal addInInst As Object, ByRef custom As System.Array) _ Implements Extensibility.IDTExtensibility2.OnConnection 344 Chapter 15 TEAMFLY Team-Fly ® applicationObject = CType(application, EnvDTE.DTE) addInInstance = CType(addInInst, EnvDTE.AddIn) Dim tempdoc As Object Dim newguid As String = “{779C198F-F4AC-4d21-A06A-EF710D3946A5}” toolwin = applicationObject.Windows.CreateToolWindow( _ addInInstance, _ “VSUserControlHost.VSUserControlHostCtl”, _ “Scripts”, newguid, tempdoc) toolwin.Visible = True doc = CType(tempdoc, VSUserControlHostLib.IVSUserControlHostCtl) Dim asm As System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly() doc.HostUserControl(asm.Location, _ “ScriptExplorer.ScriptExplorerForm”) Try Dim commands As Commands = applicationObject.Commands Dim command1 As Command = commands.AddNamedCommand( _ addInInstance, _ “Show”, “Script Explorer”, “Shows the Script Explorer”, _ True, 59, Nothing, _ vsCommandStatus.vsCommandStatusSupported + _ vsCommandStatus.vsCommandStatusEnabled) Dim viewMenu As CommandBarPopup = _ applicationObject.CommandBars(“MenuBar”). _ Controls(“&View”) Dim viewMenuBar As CommandBar = viewMenu.CommandBar Dim othersMenu As CommandBarPopup = _ viewMenu.Controls(“Other Windows”) Dim othersBar As CommandBar = othersMenu.CommandBar command1.AddControl(othersBar, 1) Catch End Try End Sub Public Sub Exec(ByVal cmdName As String, ByVal executeOption As _ vsCommandExecOption, ByRef varIn As Object, ByRef varOut As Object, _ ByRef handled As Boolean) Implements IDTCommandTarget.Exec handled = False If (executeOption = vsCommandExecOption. _ vsCommandExecOptionDoDefault) Then If cmdName = “ScriptExplorer.Connect.Show” Then toolwin.Visible = True handled = True Exit Sub End If End If End Sub Integrating with Other Products 345 Public Sub QueryStatus(ByVal cmdName As String, ByVal neededText _ As vsCommandStatusTextWanted, ByRef statusOption As _ vsCommandStatus, ByRef commandText As Object) _ Implements IDTCommandTarget.QueryStatus If neededText = EnvDTE.vsCommandStatusTextWanted. _ vsCommandStatusTextWantedNone Then If cmdName = “ScriptExplorer.Connect.Show” Then statusOption = CType(vsCommandStatus. _ vsCommandStatusEnabled + vsCommandStatus. _ vsCommandStatusSupported, vsCommandStatus) Else statusOption = vsCommandStatus.vsCommandStatusUnsupported End If End If End Sub End Class Now here’s the form, as shown in Figure 15.2. To create this form, follow these steps: 1. Add a new User Control. 2. Place a StatusBar control on the form. 3. Place a TreeView control on the form. 4. Set the TreeView’s Dock property to Fill. Make sure its ShowPlusMinus property is True, and its ShowRootLines property is True. 5. Click the Nodes property to select it, then click the button with an ellipses ( ) on it to open the TreeNode Editor, which is shown in Figure 15.3. 6. In the TreeNode Editor, click the Add Root button. Then type the word Scripts into the Label box. Click OK to close the TreeNode Editor. 7. In the Toolbox, double-click the ContextMenu control to add a context menu to the form. 8. Click the ContextMenu control in the component tray beneath the form; the menu editor will open, as shown in Figure 15.4. Add the names Choose directory and Edit, as shown in the figure. Figure 15.2 The form for the add-in has a StatusBar and a TreeView control. 346 Chapter 15 Figure 15.3 Use the TreeNode Editor to add a root node to the TreeView control. 9. Now switch to the code editor by right-clicking on the form, and in the popup menu choosing View Code. 10. In the drop-down list in the upper left of the code editor, choose MenuItem1. Then in the drop-down list on the right, choose Click to add a new Click handler for the menu item, as shown in Figure 15.5. Then do the same to add handlers for the DoubleClick event of TreeView1 and the Click event for MenuItem2. Figure 15.4 Use the Menu Editor to add two menu items. Integrating with Other Products 347 Figure 15.5 The drop-down listboxes let you add event handlers. 11. Now enter the following code, some of which will already be present, so you won’t have to type it in. Specifically, notice that I added some initialization code to the New constructor; I also added the event handlers after the #End Region statement. Imports System.IO Imports System.Windows.Forms Public Class ScriptExplorerForm Inherits System.Windows.Forms.UserControl #Region “ Windows Form Designer generated code “ Public Sub New() MyBase.New() ‘This call is required by the Windows Form Designer. InitializeComponent() ‘Add any initialization after the InitializeComponent() call TopNode = TreeView1.Nodes.Item(0) 348 Chapter 15 If Not Directory.Exists(ScriptDir) Then Directory.CreateDirectory(ScriptDir) End If UpdateScripts() End Sub ‘UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub ‘Required by the Windows Form Designer Private components As System.ComponentModel.IContainer Friend WithEvents TreeView1 As System.Windows.Forms.TreeView Friend WithEvents ContextMenu1 As System.Windows.Forms.ContextMenu Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem Friend WithEvents StatusBar1 As System.Windows.Forms.StatusBar Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem <System.Diagnostics.DebuggerStepThrough()> Private Sub _ InitializeComponent() Me.TreeView1 = New System.Windows.Forms.TreeView() Me.ContextMenu1 = New System.Windows.Forms.ContextMenu() Me.MenuItem1 = New System.Windows.Forms.MenuItem() Me.StatusBar1 = New System.Windows.Forms.StatusBar() Me.MenuItem2 = New System.Windows.Forms.MenuItem() Me.SuspendLayout() ‘ ‘TreeView1 ‘ Me.TreeView1.ContextMenu = Me.ContextMenu1 Me.TreeView1.Dock = System.Windows.Forms.DockStyle.Fill Me.TreeView1.ImageIndex = -1 Me.TreeView1.Name = “TreeView1” Me.TreeView1.Nodes.AddRange(New System.Windows.Forms.TreeNode() _ {New System.Windows.Forms.TreeNode(“Scripts”)}) Me.TreeView1.SelectedImageIndex = -1 Me.TreeView1.Size = New System.Drawing.Size(456, 150) Integrating with Other Products 349 Me.TreeView1.TabIndex = 0 ‘ ‘ContextMenu1 ‘ Me.ContextMenu1.MenuItems.AddRange(New System.Windows.Forms. _ MenuItem() {Me.MenuItem1, Me.MenuItem2}) ‘ ‘MenuItem1 ‘ Me.MenuItem1.Index = 0 Me.MenuItem1.Text = “Choose directory” ‘ ‘StatusBar1 ‘ Me.StatusBar1.Location = New System.Drawing.Point(0, 134) Me.StatusBar1.Name = “StatusBar1” Me.StatusBar1.Size = New System.Drawing.Size(456, 16) Me.StatusBar1.TabIndex = 1 Me.StatusBar1.Text = “StatusBar1” ‘ ‘MenuItem2 ‘ Me.MenuItem2.Index = 1 Me.MenuItem2.Text = “Edit” ‘ ‘ScriptExplorerForm ‘ Me.Controls.AddRange(New System.Windows.Forms.Control() { _ Me.StatusBar1, Me.TreeView1}) Me.Name = “ScriptExplorerForm” Me.Size = New System.Drawing.Size(456, 150) Me.ResumeLayout(False) End Sub #End Region Private Sub MenuItem1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MenuItem1.Click Dim newdir As String = InputBox(“Enter the new directory”) If newdir <> “” Then If Directory.Exists(newdir) Then ScriptDir = newdir End If 350 Chapter 15 End If UpdateScripts() End Sub Private Sub UpdateScripts() TreeView1.BeginUpdate() TopNode.Nodes.Clear() Dim filename As String For Each filename In Directory.GetFiles(ScriptDir) Dim node As New TreeNode(Path.GetFileName(filename)) node.Tag = filename TopNode.Nodes.Add(node) Next TreeView1.ExpandAll() TreeView1.EndUpdate() StatusBar1.Text = ScriptDir End Sub Private Sub TreeView1_DoubleClick(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles TreeView1.DoubleClick Dim node As TreeNode = TreeView1.SelectedNode If Not node Is Nothing Then If node Is TopNode Then Exit Sub Dim procinfo As New ProcessStartInfo() procinfo.UseShellExecute = True procinfo.FileName = node.Tag Dim proc As Process = Process.Start(procinfo) End If End Sub Private Sub MenuItem2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MenuItem2.Click Dim node As TreeNode = TreeView1.SelectedNode If Not node Is Nothing Then If node Is TopNode Then Exit Sub Connect.applicationObject.ItemOperations.OpenFile(node.Tag) End If End Sub Private ScriptDir As String = “c:\scripts” Private TopNode As TreeNode = Nothing End Class Integrating with Other Products 351 When you build this add-in and run it, Visual Studio .NET will now have a tool win- dow that lists scripts. I put all my scripts in a single directory called c:\scripts, which this tool window lists by default. If you double-click a script in the list, the script will run. If you right-click the script’s name, you can choose Edit to edit the script right inside the Visual Studio .NET IDE. Or you can right-click and type in a new directory. (You’re welcome to enhance the form to include an OpenFile dialog to choose a dif- ferent directory.) As you can see, this add-in simply executes whichever file you double-click. Thus, you can also use this add-in to spawn other programs besides scripts. And if you’re adventurous, you can play with the procinfo and Process.Start items in the TreeView1.DoubleClick event handler to capture the standard output and standard error, writing it to a tool window. (If you do this, drop me a line at readers@jeffcogswell.com; I’ll add a couple of the ones that work to the official Web site for this book. And if you have other additions, don’t hesitate to share them with me and the other readers in the forum on the book’s Web site.) Moving Forward This chapter showed you how you can take the automation object exposed by Visual Studio .NET and control the IDE from pretty much any program that supports COM automation. To demonstrate this capability, I used Delphi, Python, and the Windows Script Host, or WSH. I then took you through an interesting add-in that lets you spawn these other programs so you can, effectively, write your macros in any language you want. The next chapter, “Deploying Your Macros and Add-ins,” begins Part IV, “Deploying and Supercharging.” In it, I talk about the various issues regarding the deployment of your add-ins to other computers, focusing in particular on some important points regarding Office add-ins. In the final chapter of this book, Chapter 17, “Supercharging Visual Studio .NET,” I close some open ends about add-ins and macros. 352 Chapter 15 PART Four Deploying and Supercharging [...]... a vsmacros extension ■ ■ Users of the macros have full access to the source code ■ ■ If your macros call into an assembly (many of mine call into VBMacroUtilities), you will want to distribute the assembly with the macros TE 364 If you have a simple set of macros, all in a single project, and the macros do not use any special assemblies besides those that are standard with the Visual Studio NET and. .. and let the user unzip Team-Fly® Deploying Your Macros and Add-ins them and copy them into a directory (Remember, these are users of Visual Studio NET, hence you can assume, programmers.) Then the users can install the vsmacros file as before Or you can get fancy and build a Setup project I consider a Setup project a mark of professionalism If somebody gives me a zip file and I create a directory and. .. vsmacros file The user can then double-click this shortcut, which will launch Visual Studio NET and automatically install the vsmacros file Remember, the vsmacros file will be in the subdirectory under Program Files, which your deployment program created on the user’s computer The shortcut on the desktop will be a link to the vsmacros file Therefore, after the user installs the vsmacros file to Visual. .. Right-click the vsmacros file in the right pane, and in the popup menu choose Create Shortcut to MyMacros.vsmacros (or whatever your vsmacros file is called) Optionally, you might type a new name for the shortcut, such as Install MyMacros.vsmacros Remember, this icon will install the macros into Visual Studio NET, so make this an appropriate name 4 The shortcut is now in the Application Folder, but... CHAPTER 17 Supercharging Visual Studio NET In this, the final chapter of the book, I wrap-up add-in development in Visual Studio NET by, first, showing you how you can create a new page in the Options dialog box through which the IDE users can configure your add-in; next, providing another addin I’ve found a need for and thought you might, too; and then listing a few handy third-party add-ins that you might... simple: Distribute a copy of your vsmacros file The recipients can copy the file into whichever directory they want and then install the file by opening the Macro Explorer (choose View➪Other Windows➪Macro Explorer), then right-clicking the Macros item in the Macro Explorer, and in the popup menu choosing Load Macro Project, and, finally, browsing to the vsmacros file and opening it The file will then... project in the Macros Explorer before building the Setup project The reason for the first point is that if the users have a valid installation of Visual Studio NET (which they should, otherwise they wouldn’t be downloading macros for Visual Studio NET), they will already have these additional assemblies To remove these files from the setup, open the file’s properties in the File System Editor and set the... directory The reason for the third point is that Visual Studio NET puts a lock on any macro project files that are loaded This will cause the Setup project to refuse to build, displaying the following message: Unable to find source file ‘C:\dev\Projects\MiscWork \Visual Studio Projects\VSMacros\OLEProjects\OLEProjects.vsmacros’ for file ‘OLEProjects.vsmacros’, located in ‘[TARGETDIR]’, the file may be... a few handy third-party add-ins that you might want to obtain I close the chapter and the book by talking a bit about the Common Language Infrastructure (CLI) and where to go if you want to take your development further This final section doesn’t mention add-ins and macros, but when your mind-set is on enhancing Visual Studio NET, you’ll find that a whole world exists beyond them For example, you can... person or organization, and all people and organizations developing managed add-ins share this same mscoree.dll file (unless they create their own unmanaged COM component) And since this file is not signed, when Office runs in high security mode, it will refuse to let the mscoree.dll add-in run (Remember, Office considers the COM component itself the add-in, even though you and I both know the real . _ “ScriptExplorer.ScriptExplorerForm”) Try Dim commands As Commands = applicationObject.Commands Dim command1 As Command = commands.AddNamedCommand( _ addInInstance, _ “Show”, “Script Explorer”,. Then statusOption = CType(vsCommandStatus. _ vsCommandStatusEnabled + vsCommandStatus. _ vsCommandStatusSupported, vsCommandStatus) Else statusOption = vsCommandStatus.vsCommandStatusUnsupported End. viewMenuBar As CommandBar = viewMenu.CommandBar Dim othersMenu As CommandBarPopup = _ viewMenu.Controls(“Other Windows”) Dim othersBar As CommandBar = othersMenu.CommandBar command1.AddControl(othersBar,

Ngày đăng: 12/08/2014, 16:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan