Visual Studioと通信(F#)

通常、VisualStudioに機能を追加する際は、VSIXを作成してインストールします。

今回は外部からVisualStudioと通信してみます。

VisualStudioを見つける(DTEの取得)

RunningObjectTableからDTEのオブジェクトを取得しています。

DTEはIDE以外のも取れることがあります。

open System
open System.Runtime.InteropServices
open System.Runtime.InteropServices.ComTypes
open EnvDTE

[<DllImport("ole32.dll")>]
extern int GetRunningObjectTable(int reserved, IRunningObjectTable& pprot)

let mutable runningObjectTable = null
if GetRunningObjectTable(0, &runningObjectTable) <> 0 then
    failwith "GetRunningObjectTable failed"

let mutable enumMoniker = null
runningObjectTable.EnumRunning(&enumMoniker)

let monikers = 
    [ let moniker = [| null |]
        while enumMoniker.Next(1, moniker, IntPtr.Zero) = 0 do
        yield moniker.[0] ]

let getDte (moniker : IMoniker) =
    let mutable dte = null
    if runningObjectTable.GetObject(moniker, &dte) <> 0 then
        failwith "GetObject failed"
    match dte with
    | :? DTE as x -> Some x
    | _           -> None

let dtes = monikers |> List.choose getDte


テキストを送ってみる

"Target"ソリューションの現在のカーソルの位置に"hello"を埋め込んでいます。

DTEのリストから対象のIDEを取得する方法は自由に変更してください。

let dte = dtes |> List.find (fun x -> IO.Path.GetFileNameWithoutExtension(x.Solution.FileName) = "Target")

let document = dte.ActiveDocument.Object() :?> TextDocument

document.Selection.ActivePoint.CreateEditPoint().Insert("hello")
f:id:any-programming:20170227180520p:plain f:id:any-programming:20170227180530p:plain