前三篇简单介绍了VSTA的用途以及开发前期准备,这一篇将介绍具体的开发。
我们先实现一个最简单的功能,打开VSTA IDE编程环境。
首先在VSTASAMPLE项目中,添加如下引用:
以及:
Microsoft Development Enviroment 8.0.
DTEProvider 1.0 Type Library
添加HostItemProvider.cs,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.AddIn.Contract;
using System.AddIn.Contract.Automation;
using System.Runtime.Remoting;
using Microsoft.VisualStudio.Tools.Applications.Contract;
using Microsoft.VisualStudio.Tools.Applications;
namespace VSTASample
{
internal class HostItemProvider : ContractAdapterBase,
IHostItemProviderContract
{
private VSTAApplication application;
public HostItemProvider( VSTAApplication application,
TypeInfrastructureManager typeInfrastructureManager )
: base(typeInfrastructureManager)
{
this.application = application;
}
protected override IContract QueryContract( string contractId )
{
if(String.Compare(contractId,
typeof(IHostItemProviderContract).AssemblyQualifiedName,
StringComparison.Ordinal) == 0)
{
return (IContract)this;
}
return base.QueryContract(contractId);
}
public IRemoteObjectContract GetHostObject( string objectType, string cookie )
{
if(String.Compare(objectType,
typeof(RCS.Common.VSTA.VSTAApplication).FullName,
StringComparison.Ordinal) == 0)
{
RemoteObjectAdapter adapter = new RemoteObjectAdapter(
typeof(RCS.Common.VSTA.VSTAApplication),
application, TypeInfrastructureManager);
return adapter;
}
throw new ArgumentOutOfRangeException();
}
protected override string RemoteToString()
{
return this.ToString();
}
protected override int GetRemoteHashCode()
{
return this.GetHashCode();
}
protected override bool RemoteEquals( IContract contract )
{
if(contract == null)
return false;
if(!System.Runtime.Remoting.RemotingServices.
IsObjectOutOfAppDomain(contract))
{
HostItemProvider contractAdapter =
contract as HostItemProvider;
return this.Equals(contractAdapter);
}
return false;
}
}
}
添加一个IDEManagement.cs,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.VisualStudio.Tools.Applications;
using Microsoft.VisualStudio.Tools.Applications.Contract;
using Microsoft.VisualStudio.Tools.Applications.DesignTime.Interop;
using System.AddIn.Contract.Automation;
using EnvDTE80;
using VSTADTEProvider.Interop;
using System.IO;
using System.Collections;
using EnvDTE;
namespace VSTASample
{
///
/// VSTA操作方法类
///
internal partial class IDEManagement
{
private VSTAApplication application;
//private Context macroContext;
//private AddInCollection addInCollection;
private IHostItemProviderContract itemProvider;
private TypeInfrastructureManager typeInfrastructureManager;
private EnvDTE.DTE vstaDTE;
private EnvDTE.Project macroProject;
//private IEntryPointContract[] hostItems;
private string hostID;
private string templateName;
///
/// 初始化Extension类的新实例。
///
internal IDEManagement()
{
InitializeTypeInfrastructureManager();
}
internal void Connect(VSTAApplication application, string hostID,string templateName)
{
this.application = application;
this.application.IDEManagement = this;
this.hostID = hostID;
this.templateName = templateName;
this.itemProvider = new HostItemProvider(application,TypeInfrastructureManager);
//this.macroPath = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin";
//LoadAddIns();
//InitializeMenus();
}
Internal Properties
///
/// 打开脚本编程环境
///
/// 脚本程序所在目录
/// 脚本程序工程文件名称(*.vbproj)
///
public bool StartIDE(string projectDirectory, string projectFilename)
{
EnsureIDE(hostID);
if (vstaDTE.MainWindow.Visible)
{
//vstaDTE.MainWindow.Activate();
vstaDTE.MainWindow.SetFocus();
return true;
}
else
{
vstaDTE.MainWindow.Visible = true;
vstaDTE.MainWindow.WindowState = EnvDTE.vsWindowState.vsWindowStateMaximize;
string projectFilePath = System.IO.Path.Combine(projectDirectory, projectFilename);
if (System.IO.File.Exists(projectFilePath))
{
OpenMacroProject(projectFilePath);
}
else
{
try
{
CreateNewMacroProject(projectDirectory, projectFilename);
}
catch(Exception e)
{
MessageBox.Show(
e.Message,
hostID, MessageBoxButtons.OK, MessageBoxIcon.Error);
this.vstaDTE.Quit();
vstaDTE = null;
return false;
}
}
return true;
}
}
private void EnsureIDE(string hostID)
{
if (this.vstaDTE == null)
{
try
{
IDTEProvider dteProvider = new VSTADTEProviderClass();
//string HostID = "MyVSTADLLTest";
UInt32 TimeOut = 10000;
vstaDTE = dteProvider.GetDTE(hostID, TimeOut);
System.Diagnostics.Debug.Assert(this.vstaDTE != null);
}
catch
{
// If DTEProvider does not work, try co-creating DTE instead.
object objDTE = new EnvDTE.DTE();
this.vstaDTE = (EnvDTE.DTE)objDTE;
}
//vstaDTE.MainWindow.Visible = true;
//增加关闭IDE窗口时关闭vsta.exe进程以及编译
EnvDTE.CommandEvents commandEvents = vstaDTE.Events.get_CommandEvents("{00000000-0000-0000-0000-000000000000}", 0);
commandEvents.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(commandEvents_BeforeExecute);
//get and subscribe to the File.Exit event prior to execution
EnvDTE.CommandEvents exitCommand = vstaDTE.Events.get_CommandEvents("{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 229);
exitCommand.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(exitCommand_BeforeExecute);
}
}
///
/// 关闭IDE
///
public void ExitIDE()
{
if(this.vstaDTE != null)
{
if(this.vstaDTE.Mode == EnvDTE.vsIDEMode.vsIDEModeDebug)
{
this.vstaDTE.Debugger.Stop(true);
}
this.macroProject.Save(null);
this.vstaDTE.Quit();
}
private void CreateNewMacroProject(string projectDirectory, string projectFileName)
{
Solution2 sol = (Solution2)vstaDTE.Solution;
//string projectTemplatePath = @"C:\ShapeAppSamples\VSTATest\templates\VisualBasic\1033\";
string projectTemplatePath = sol.GetProjectTemplate(templateName, "VisualBasic");
//string targetProjectDirectory = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros";
//string targetProjectFilename = "MyEventSampleMacro.vbproj";
this.vstaDTE.Solution.AddFromTemplate(projectTemplatePath,projectDirectory, projectFileName, true);
this.vstaDTE.Solution.SolutionBuild.Build(true);
}
private void OpenMacroProject(string projectFilePath)
{
//string projectFilePath = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\MyEventSampleMacro.vbproj";
this.macroProject = this.vstaDTE.Solution.AddFromFile(projectFilePath, true);
//vstaDTE.MainWindow.Visible = true;
}
EnvDTE.CodeElement FindCodeElementInCodeElements(EnvDTE.CodeElements codeElems, EnvDTE.vsCMElement kind, string fullName)
{
foreach (EnvDTE.CodeElement codeElem in codeElems)
{
if (codeElem.Kind == kind)
{
if (codeElem.FullName == fullName)
{
if (codeElem.Kind == EnvDTE.vsCMElement.vsCMElementFunction)
{
EnvDTE.CodeFunction codeFunc = (EnvDTE.CodeFunction)codeElem;
if (codeFunc.IsOverloaded)
{
if (codeFunc.Parameters.Count != 0)
{
continue;
}
}
}
return codeElem;
}
}
}
return null;
}
private void exitCommand_BeforeExecute( string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault )
{
//Project.IsDirty is always false, so use .Saved which starts true
if(this.macroProject.Saved == true)
{
//prompt the user to save the project
this.macroProject.Save(null);
//change the saved state
this.macroProject.Saved = false;
this.vstaDTE.Solution.SolutionBuild.Build(true);
}
//quit the IDE
this.vstaDTE.Quit();
this.vstaDTE = null;
}
private void commandEvents_BeforeExecute( string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault )
{
EnvDTE.Command objCommand = default(EnvDTE.Command);
//string sCommandName = null;
//break here to check out any commands you are interested in
objCommand = vstaDTE.Commands.Item(Guid, ID);
//if((objCommand != null))
//{
// sCommandName = objCommand.Name;
// if(sCommandName.Equals("Something.WorthWatching"))
// {
// //do something
// }
//}
}
private void InitializeTypeInfrastructureManager()
{
if (typeInfrastructureManager == null)
{
typeInfrastructureManager = new TypeInfrastructureManager();
// This was auto-generated from ProxyGen with the /h:hostmapfile commandline argument.
global::System.Type hostType;
global::System.Type proxyType;

hostType = typeof(global::VSTASample.VSTAApplication);
proxyType = typeof(NonProxiableType<global::VSTASample.VSTAApplication>);
typeInfrastructureManager.CanonicalNameToTypeMap.Add("VSTASample, VSTASample.VSTAApplication", proxyType);
typeInfrastructureManager.TypeToCanonicalNa垃圾广告p.Add(hostType, "VSTASample, VSTASample.VSTAApplication");
}
}
}
}这里,我们为了方便不同的项目调用,用一个操作类来发布,添加一个VSTAHelper.cs,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using EnvDTE;
using System.Collections;
namespace VSTASample
{
///
/// VSTA操作类
///
public class VSTAHelper
{
private static VSTAHelper instance;
///
/// VSTAHelper类单一实例
///
public static VSTAHelper Instance
{
get
{
if(VSTAHelper.instance == null)
{
VSTAHelper.instance = new VSTAHelper();
}
return VSTAHelper.instance;
}
}
private VSTAApplication app;
///
/// 初始化类的实例。
///
private VSTAHelper()
{
{
app = new VSTAApplication();
}
}
///
/// 打开脚本编程环境
///
///
/// 脚本程序所在目录(如:C:\ShapeAppSamples\MyVSTADLLTest\Macros)
/// 脚本程序工程文件名称(*.vbproj)
///
/// private VSTAHelper vstaHelper = new VSTAHelper();
/// vstaHelper.StartIDE(@"..\Solutions\自动计量\script\Demo","Demo.vbproj");
///
public void StartIDE( string projectDirectory, string projectFilename )
{
//using(MessageFilter messageFilter = new MessageFilter())
{
app.IDEManagement.StartIDE(projectDirectory, projectFilename);
}
}
///
/// 关闭IDE
///
///
/// private VSTAHelper vstaHelper = new VSTAHelper();
/// vstaHelper.ExitIDE();
///
public void ExitIDE()
{
app.IDEManagement.ExitIDE();
}
}
internal partial class VSTAApplication
{
private IDEManagement ideManagement;
///
/// 操作方法类
///
public IDEManagement IDEManagement
{
get
{
if(this.ideManagement == null)
{
ideManagement = new IDEManagement();
ideManagement.Connect(this, "VSTAHelper", "dlladdin.zip");
}
return ideManagement;
}
set
{
ideManagement = value;
}
}
}
}
编译生成。
下面就是新建个winform项目,使用操作类即可。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12639172/viewspace-612019/ ,如需转载,请注明出处,否则将追究法律责任。