Overview



OverviewMicrosoft Visual Studio Tools for Applications 2012 (VSTA) gives you a way to enable end users to customize your existing applications using Visual Basic and Visual C#. You can incorporate the use of the Visual Studio integrated development environment (IDE) into your application to enable end user customization. End-user developers can use the IDE to customize the application by creating add-ins that extend the functionality of the application to meet their needs. Using Visual Studio Tools for Applications 2012 Visual Studio Tools for Applications 2012 provides two primary modes of operation: with Visual Studio 2012 Professional, Premium or Ultimate installed and standalone. In standalone mode, VSTA provides your application with the means to load, compile, and run end user customizations. With Visual Studio 2012 Professional, Premium or Ultimate installed, VSTA extends that functionality with the means to edit and debug those customizations. Visual Studio Tools for Applications 2012 presents a new and simplified API for integrating design-time experiences into your application. Host application integrations can be implemented by using either managed (Visual C# or Visual Basic .NET) or unmanaged (Visual C++) code. The VSTA hosting API enables you to integrate your application because the API simplifies tasks such as finding the installation of Visual Studio, launching the external process, and synchronizing save state.Visual Studio Tools for Applications 2012 provides the ability to upgrade projects from Visual Studio 2005 Tools for Applications and Visual Studio 2008 Tools for Applications, compile, and run them. Visual Studio Tools for Applications 2012 does not require a runtime library for end user customizations. This gives the integrator the flexibility to choose the method of running user code best tailored to the host application. The Microsoft .NET Framework includes the Managed Add-in Framework, which can be used to run add-ins built on Visual Studio 2008 Tools for Applications. Minimum system requirements:Windows 7 .NET Framework 4.52 GB of RAM4 MB of hard disk spaceRuntime requirement:Visual C++ Redistributable for Visual Studio 2012 Update 1To enable editing and debugging:Microsoft Visual Studio 2012 Professional, Premium or UltimateGetting StartedTo integrate an application with Visual Studio Tools for Applications 2012, you must understand a few simple concepts.DefinitionsHost Application: An application that is capable of being extended through end user code. A host application “hosts” the end user code by giving it the facilities to be compiled and run, facilitated by the technologies in VSTA. Integrated Development Environment (IDE): An application (in this case, Visual Studio 2012) that allows a user to compile, edit, and debug code. Visual Studio 2012Project Template: A collection of source files and XML that are used at runtime for the creation of projects that can be customized by end user code. Session: An instance of a collection of projects that can be associated with one IDE. This encapsulates all of the services that can be done between zero or more projects and a single running IDE instance. VSTAX: An Open Packaging Container (OPC) file that contains one or more project templates. A VSTAX file is typically created by the host application vendor, shipped with the application, and used at runtime to create a project for an end user to customize.VSTA includes versions of the hosting API for both managed and unmanaged integration. This document will demonstrate use of the API in Visual C#, but all scenarios can be accomplished using Visual C++ and Visual Basic .NET as well. Installing the Visual Studio Tools for Applications 2012 SDKBefore you can install and run this version of VSTA, the Microsoft .NET Framework 4.5 must also be installed.Microsoft ships a software development kit (SDK) for VSTA apart from the VSTA download. After the VSTA SDK is installed, its components are placed into the Program Files (x86)\Microsoft SDKs\VSTA\11.0 folder. To build an application, you need only the .NET Framework SDK (available as a free download from Microsoft), but examples in this document will be shown using Visual Studio 2012. Launching an IDE from Your Host ApplicationAfter the VSTA SDK is installed, you can launch Visual Studio from your application by using Visual C# if you add a reference to one assembly and then write three lines of code. To enable an application to launch the IDE: In Visual Studio 2012, create a WPF application, and name it “MyVSTAHost”.In Solution Explorer, open the shortcut menu for the MyVSTAHost project node, and choose Add Reference.In the Add Reference dialog box, choose Microsoft.VisualStudio.Tools.Applications version 11.0.0.0, and then choose the Add button.Add a button to the default form, and then add an event handler to the button.Add the following statement to your form: using VSTA = Microsoft.VisualStudio.Tools.Applications;Add the following code to your event handler: private VSTA.Session _session; private void button1_Click(object sender, EventArgs e) { if (_session == null) { var sessionMgr = VSTA.SessionManager.Create("MyHostApp"); _session = sessionMgr.CreateSession(); } _session.Ide.Show(); }This code does the following: Creates a session if one hasn’t already been created. This starts up the base-level scaffolding required to communicate with an IDE and manage projects.On the session’s Ide instance, shows the IDE. This will implicitly launch the IDE process, open a communication channel to the IDE, and tell the IDE to show the main window. NOTES: A session’s name must be unique in the context of the running Host Application instance. In other words, the “if(_session == null)” condition prevents another session from being created with the same name each time a user chooses the button. This situation can lead to a deadlock condition when the Ide object is accessed. Session and SessionManager objects are, in fact, IDisposable. If you use these objects, you must use proper implementation of IDisposable for classes that hold onto instances of these objects. If you failing to hold onto instances of these objects, the .NET garbage collector can dispose of them, which leads to exceptions.Creating a Project TemplateTo creating a project in VSTA, you must choose a project template. This template provides the basic framework of project source files needed to enable end users to add their code to the solution. In VSTA, project templates are packaged in VSTAX files. These files contain one or more templates that can be redistributed with your host application. These project templates work differently from project templates that are deployed with Visual Studio 2012, in that VSTA templates do not need to be installed with Visual Studio. This allows the host application complete control of template deployment. VSTA templates provide built-in facilities for replacement tokens (for example, “$projectname$”), guid generation (for example, “$guid2$”), and SNK file generation during project creation. You can create templates for VSTA projects by using TemplateGenerator.exe, a command-line tool included in the VSTA SDK in the folder %ProgramFiles(x86)%\Microsoft SDKs\VSTA\11.0\Tools. You can use this tool to create a VSTAX file, which VSTA can then consume to create projects.To create a template:In Visual Studio 2012, create a C# Class Library Project, and name it “TemplateProject”.Rename Class1 to “AddIn”, and add the following method:public static void Init(){ // Place add-in start-up code here}In the file AddIn.cs, replace all instances of “TemplateProject” with “$safeprojectname$”, which will be replaced with the project’s actual name when it is created from the template.In the file AssemblyInfo.cs, replace all instances of “TemplateProject” with “$safeprojectname$”, which will be replaced with the project’s actual name when it is created from the template. Replace the GUID in the Guid Attribute with “$guid2$”, which will be replaced with a generated GUID when a project is created from the template.In the fileTemplateProject.csproj, replace all instances of “TemplateProject” with “$safeprojectname$”, which will be updated with the project’s actual name when it is created from the template. Replace the contents of the ProjectGuid element with “{$guid1$}”, which will be replaced with a generated GUID when a project is created from the template. In the PropertyGroup element, add an element ‘<ProjectTypeGuids>’, as described later in this document. The two GUIDs after this step represent the VSTA and C# project types respectively. To create a template for Visual Basic, replace the C# project GUID (FAE04EC0-301F-11D3-BF4B-00C04F79EFBC) with the Visual Basic project GUID (F184B08F-C81C-45F6-A57F-5ABD9991F28F).<ProjectTypeGuids>{30D016F9-3734-4E33-A861-5E7D899E18F3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>After the final Import element (Microsoft.CSharp.targets), insert the ProjectExtensions element:<ProjectExtensions> <VisualStudio> <FlavorProperties GUID="{30D016F9-3734-4E33-A861-5E7D899E18F3}"> <ProjectProperties HostName = "MyHostApp" HostPackage="{B3A685AA-7EAF-4BC6-9940-57959FA5AC07}" ApplicationType="" Language="cs" TemplatesPath="" /> </FlavorProperties> </VisualStudio></ProjectExtensions>All of the attributes are required, or the project won't load in VSTA.In the TemplateProject solution folder, add an XML file that's named manifest.xml:<?xml version="1.0" encoding="utf-8" ?><VstaTemplates xmlns="" TemplateVersion="1.0"> <ProjectTemplate ProjectType="msBuild" TemplateName="csaddin"> <ProjectItems> <ProjectItem ReplaceParameters="true" SourceFilePath="TemplateProject\TemplateProject.csproj" TemplateFilePath="csaddin\AddIn.csproj" TargetFilePath="$projectname$.csproj" TargetItemType="Project" /> <ProjectItem ReplaceParameters="true" SourceFilePath="TemplateProject\AddIn.cs" TemplateFilePath="csaddin\AddIn.cs" TargetFilePath="AddIn.cs" /> <ProjectItem ReplaceParameters="true" SourceFilePath="TemplateProject\Properties\AssemblyInfo.cs" TemplateFilePath="csaddin\AddIn.Designer.cs" TargetFilePath="Properties\AssemblyInfo.cs" /> </ProjectItems> </ProjectTemplate></VstaTemplates>Open a command prompt in the TemplateProject solution folder, and run the following command:"%ProgramFiles(x86)%\Microsoft SDKs\VSTA\11.0\Tools\TemplateGenerator.exe" /manifest:manifest.xml /output:template.vstaxThis command will create the template file template.vstax.NOTES:You can find the schema for the manifest XML file (VstaTemplateManifestSchema.xsd) in the %ProgramFiles(x86)%\Microsoft SDKs\VSTA\11.0\Tools\ folder. This file contains comments on the meaning of the individual elements and attributes.The manifest file allows multiple templates to be specified and packaged into a single VSTAX file.Creating a Project from a TemplateTo create a VSTA project from your VSTAX, you must add a small amount of code.In Visual Studio, perform the following: Add your VSTAX file to your project, and set its Copy to Output Directory property to Copy always.Add a button and named “New” to your form, and add an event handler to the button.Add the following code to the event handler:private VSTA.Project _project;private void button2_Click(object sender, EventArgs e){ if (_session == null || _project != null) { //Error handling... return; } var storage = VSTA.ProjectStorage.CreateStorageFromTemplate("template.vstax", "csaddin", "VSTASample", null); _project = _session.LoadProject(storage);}NOTES:In addition to the standard Visual Studio replacement parameters (such as $safeprojectname$), VSTA supports defining custom replacement parameters by passing in a dictionary of key value pairs to the CreateStorageFromTemplate method. These pairs should be in the following format:{“$key$”, “value”}SNK file generation requires the .NET Framework SDK to be installed when you create a project from the template.Saving and Loading a ProjectTo save and load a project from a file, you must first create a class that implements the VSTA IProjectStorage interface. IProjectStorage is a simple mechanism that can look up any item by a name and get back a stream. This can be as simple as a table of binaries or a virtual file system. One IProjectStorage is associated with each project, and item names are not guaranteed to be unique across more than one project. The following example implements IProjectStorage in a MyProjectStorage class. In Visual Studio, perform the following: Add a class named “MyProjectStorage” to your project.Add a the following statement: using VSTA = Microsoft.VisualStudio.Tools.Applications;Implement IProjectStorage to use the file system as a backing store for all items in your project: class MyProjectStorage : VSTA.IProjectStorage { string _rootDirectory; public MyProjectStorage(string pathRoot) { _rootDirectory = pathRoot; } public bool ItemExists(string itemName) { string fileName = System.IO.bine(_rootDirectory, itemName); return System.IO.File.Exists(fileName); } public System.IO.Stream OpenItem(string itemName, bool writeAccess) { string fileName = System.IO.bine(_rootDirectory, itemName); System.IO.FileMode mode; if (writeAccess) mode = System.IO.FileMode.OpenOrCreate; else mode = System.IO.FileMode.Open; return System.IO.File.Open(fileName, mode); } }Add a button named “Save” to your form, and add an event handler to the button.Add the following code to the event handler: if (_project != null) { MyProjectStorage outputProject = new MyProjectStorage("ProjectName"); _project.Save(outputProject); }When the user chooses the “Save” button in your form, the project and all its items will be saved to a folder named “ProjectName” under the application’s current working directory. You may need to create the “ProjectName” folder and “Properties” folder if they don’t exist in the application’s current working directory.NOTE: The data in the saved items can often be read as text, but the exact format and encoding depends on the implementation of VSTA and may change. All data saved by VSTA should be treated as “opaque” to the host application. VSTA projects should be opened only through the hosting API (Microsoft.VisualStudio.Tools.Applications or the unmanaged equivalents). Compiling and Running a ProjectAfter you create a project, you build and load the add-in by using the BinaryManager class.Add a button named “Run” to your form, and add an event handler to the button.Add the following statement to your form:using System.IO;using System.Reflection; Add the following code to the event handler:private void button3_Click(object sender, EventArgs e){ if (_project == null) { //Error handling... return; } var binaryManager = _project.BinaryManager; // Find the BinaryItem for the output assembly and its .pdb file. string assemblyName = binaryManager.AssemblyName; string pdbName = Path.GetFileNameWithoutExtension(assemblyName) + ".pdb"; VSTA.BinaryItem assemblyItem = null; VSTA.BinaryItem pdbItem = null; foreach (VSTA.BinaryItem item in binaryManager.GetBinaryItems()) { string itemName = item.Name; if (String.Equals(itemName, assemblyName, StringComparison.OrdinalIgnoreCase)) { assemblyItem = item; if (pdbItem != null) break; } else if (String.Equals(itemName, pdbName, StringComparison.OrdinalIgnoreCase)) { pdbItem = item; if (assemblyItem != null) break; } } if (assemblyItem == null) { //Error handling... return; } // Get the assembly as a byte[]. Stream assemblyStream = assemblyItem.GetStream(); byte[] assemblyBytes = new byte[assemblyStream.Length]; assemblyStream.Read(assemblyBytes, 0, assemblyBytes.Length); // Get the .pdb as a byte[]. Stream pdbStream = pdbItem.GetStream(); byte[] pdbBytes = new byte[pdbStream.Length]; pdbStream.Read(pdbBytes, 0, pdbBytes.Length); // Load the raw assembly. Assembly assembly = Assembly.Load(assemblyBytes, pdbBytes); // Find the AddIn class. Type addInType = assembly.GetTypes().FirstOrDefault((t) => t.Name == "AddIn"); if (addInType == null) { //Error handling... return; } // Find the Init method. MethodInfo initMethod = addInType.GetMethod("Init"); if (initMethod == null) { //Error handling... return; } // Initialize the add-in initMethod.Invoke(null, null);}NOTES:The example provided is intended to be illustrative, not exhaustive. For example, integrators may want to hand off exposing a host object for the add-in to make calls into or running the add-in in a separate process.This example loads the assembly with its symbols; this is only necessary to support debugging and is not needed in pure run-time scenarios.Debugging a ProjectTo debug a project in the IDE, the host must implement the interface VSTA.IExternalDebugHost. This interface allows the IDE to notify the host about debugging checkpoints for loading and unloading add-ins. The following code illustrates a sample host implementation of VSTA.IExternalDebugHost: internal class ExternalDebugHostImpl: VSTA.IExternalDebugHost { private Process _loaderProcess; private static ExternalDebugHostImpl _instance = null; public static ExternalDebugHostImpl Instance { get { if (_instance == null) { _instance = new ExternalDebugHostImpl(); } return _instance; } } private Process CreateHostingProcess(string projectId) { Process hostingProcess = null; //Set process properties, and create a process. //Return the created process. return hostingProcess; } //Interface methods implementation uint VSTA.IExternalDebugHost.OnBeforeDebugStarting(string projectId) { //Check if the projectId is valid. //Create an external host process, which will host the Addin during debugging. _loaderProcess = CreateHostingProcess(projectId); //If the external debug host process is created successfully, return it // to host. if (_loaderProcess != null) { return (uint)_loaderProcess.Id; } else { //In case of any error, throw an exception. throw new InvalidProgramException(); } } void VSTA.IExternalDebugHost.OnDebugStarting(string projectId) { //Ensure the projectId is same that is being debugged. //Tell the external debug host process to start running the addin code. } void VSTA.IExternalDebugHost.OnDebugStopping(string projectId) { //Perform the needed cleanup when debugging is stopped/completed. try { if (!_loaderProcess.HasExited) { _loaderProcess.Close(); } if (_loaderProcess.ExitCode != 0) { // Perform the appropriate action. } //Perform other cleanup needed to stop debugging. } catch { } } void VSTA.IExternalDebugHost.OnDebugAttachFailed(string projectId) { //Perform the needed cleanup when debugging attach fails. try { if (!_loaderProcess.HasExited) { _loaderProcess.Close(); } if (_loaderProcess.ExitCode != 0) { //Perform the appropriate action. } //Perform other cleanup needed for failed attach. } catch { } } }To properly configure the child sessions and corresponding IDE instances for debugging, the host must pass an instance of ExternalDebugHostImpl during the creation of SessionManager._sessionManager = VSTA.SessionManager.Create( "MyHostApp", new Dictionary<string, object>() { { VSTA.SessionManagerOptions.Names.ExternalDebugHost, ExternalDebugHostImpl.Instance } });After the SessionManager is created by implementing IExternalDebugHost, the host can use the APIs in the Project class to start and stop the debugging.Add a button named “StartDebugging” to your form, and add an event handler to the button.Add the following statement to the form:using System.IO;using System.Reflection; Add the following code to the event handler: private void button4_Click(object sender, EventArgs e){ if (_project == null) { //Error handling... return; } //Request the IDE to start debugging _project.StartDebugging();}Add a button named “StopDebugging” to your form, and add an event handler to the button.Add the following code to the event handler: private void button5_Click(object sender, EventArgs e){ if (_project == null) { //Error handling... return; } //Request the IDE to stop debugging _project.StopDebugging();}NOTES:The Compiling and Running example in this document already covers how to load the assembly with its symbols in an add-in. Therefore, the code is not covered in the Debugging section. For information about how to create an add-in, see the example.When creating a SessionManager, you can also configure whether a user can initiate debugging from the IDE://To enable debugging from IDE__sessionManager = VSTA.SessionManager.Create( "MyHostApp", new Dictionary<string, object>() { { VSTA.SessionManagerOptions.Names.IdeDebuggingEnabled, true} });//To disable debugging from IDE__sessionManager = VSTA.SessionManager.Create( "MyHostApp", new Dictionary<string, object>() { { VSTA.SessionManagerOptions.Names.IdeDebuggingEnabled, false} });Shutting Down Your ApplicationWhen you are finished with a SessionManager, Session, or Project, you can close it by calling Dispose. Add the following statement to the form:using ponentModel; To provide cleanup in MyVSTAHost, add a method to your form:protected override void OnClosing(CancelEventArgs e){ if (_project != null) { _project.Dispose(); _project = null; } if (_project != null) { _session.Dispose(); _session = null; } if (_project != null) { _sessionManager.Dispose(); _sessionManager = null; }}This will dispose of the Project, Session, and SessionManager when the form closes.Advanced ConsiderationsVSTA supports two threading models: Single-Threaded Apartment (STA) and Multithreaded Apartment (MTA). You must configure VSTA to use the correct behavior for the current threading model.To use STA:_sessionManager = VSTA.SessionManager.Create( "MyHostApp", new Dictionary<string, object>() { { VSTA.SessionManagerOptions.Names.InvokeOnMainThread, true} });To use MTA:_sessionManager = VSTA.SessionManager.Create( "MyHostApp", new Dictionary<string, object>() { { VSTA.SessionManagerOptions.Names.InvokeOnMainThread, false} });Upgrading a Project from Visual Studio 2008 Tools for ApplicationsIntegrators of previous versions of VSTA may want to enable users to load existing code projects into Visual Studio Tools for Applications 2012. Facilities provided through the Microsoft.VisualStudio.Tools.Applications.ProjectStorage class provide the means to load projects from previous versions of VSTA into Visual Studio 2012, update referenced assemblies, and alter the version of the .NET runtime under which the user code can run.The following example demonstrates the following:Upgrade a VSTA 2.0 project available on the disk inside “c:\temp\VSTA2Project”. This example assumes that this project folder contains a MyVSTA2Project.csproj file and its project items (for example, .cs files).Add a reference to an assembly (for example, HostObjectModel3.dll).Remove a reference to an assembly (for example, HostObjectModel2.dll).Change the project to use the .NET Framework 4.5 and Visual Studio 2012.In Visual Studio, perform the following: Add a button named “Upgrade” to your form, and add an event handler to the button.Add the following code to the event handler: // Create an IProjectStorage from a VSTA 2.0 project.VSTA.IProjectStorage Vsta2Project = new MyProjectStorage(@"c:\temp\VSTA2Project");// Upgrade.VSTA.IProjectStorage newVSTAProject = VSTA.ProjectStorage.UpgradeVstaProject( "MyVSTA2Project.csproj", Vsta2Project, new string[] { " HostObjectModel2.dll " }, new VSTA.Reference[] { " HostObjectModel3.dll " }, VSTA.VSVersion.VS11, VSTA.TargetFramework.Version45 );// Load the upgraded project.session.LoadProject(newVSTAProject);NOTE: The instance of IProjectStorage returned by the UpgradeVstaProject API uses an internal implementation of IProjectStorage and should be used for reading only.Deploying your host application For end users to access VSTA functionality in your host application, they will need to install VSTA. VSTA is provided as a free download from the Web Platform Installer 4.0 or above. VSTA can be installed with or without Visual Studio 2012 installed. When VSTA is installed without Visual Studio 2012 Professional, Premium or Ultimate installed, your host application can load, save, compile and run a VSTA add-in. NOTE: If Visual Studio 2012 is installed after VSTA, end users will need to repair their installations to enable design-time functionality. ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download