1 people like it.

Creating Visual Studio Macros in F#

this snippet presents a way to create macros in F# to automato VS IDE environment. To compile, just open a Command prompt window and type: fsc --out:fsmacros.dll --reference:envdte.dll --target:library fsmacros.fs Where FSMACROS.FS is the file name I gave for the code. After compile, copy the dll to C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies To use, just open F# interactive in Visual Studio (CTRL+ALT+F) and type: #r “envdte”;; #r “fsmacros”;; Let dte = vs10macros.getDte “The main window title appearing in you VS 2010”;;

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
module vs10macros 
    open EnvDTE
    open System.Runtime.InteropServices 
    open System.Runtime.InteropServices.ComTypes
    open System.Diagnostics
 
    [<DllImport("ole32.dll")>] 
    extern int internal GetRunningObjectTable(uint32 reserved, IRunningObjectTable& pprot) 
 
    [<DllImport("ole32.dll")>] 
    extern int internal CreateBindCtx(uint32 reserved, IBindCtx& pctx) 
 
    let getPidByWindowName (wn:string) =
        let dvproc = Process.GetProcessesByName("devenv")
        let p = Array.tryFind (fun (px:Process) -> 
                             px.MainWindowTitle.ToLower().Contains(wn.ToLower())) dvproc
        match p with
        |Some x -> x.Id
        |None -> failwith "No process contains a window with this title"
         
    let getDte windowName  = 
       let mutable (prot:IRunningObjectTable) = null  
       let mutable (pmonkenum:IEnumMoniker) = null 
       let (monikers:IMoniker[]) =  Array.create 1 null 
       let pfeteched = System.IntPtr.Zero 
       let mutable (ret:obj) = null 
       let pid = getPidByWindowName windowName
       let endpid = sprintf ":%d" pid 
       try
           if (GetRunningObjectTable(0u, &prot) <> 0) || (prot = null) then  
               failwith "Error opening the ROT" 
           prot.EnumRunning(&pmonkenum) 
           pmonkenum.Reset() 
           while pmonkenum.Next(1, monikers, pfeteched) = 0 do 
               let mutable (insname:string) = null 
               let mutable (pctx:IBindCtx) = null 
               CreateBindCtx(0u, &pctx) |> ignore 
               (monikers.[0]).GetDisplayName(pctx, null, &insname); 
               Marshal.ReleaseComObject(pctx) |> ignore 
               if insname.StartsWith("!VisualStudio.DTE") && insname.EndsWith(endpid) then 
                   prot.GetObject(monikers.[0], &ret) |> ignore 
       finally 
           if prot <> null then Marshal.ReleaseComObject(prot) |> ignore 
           if pmonkenum <> null then Marshal.ReleaseComObject(pmonkenum) |> ignore 
       (ret :?> EnvDTE.DTE) 
module vs10macros
namespace System
namespace System.Runtime
namespace System.Runtime.InteropServices
namespace System.Runtime.InteropServices.ComTypes
namespace System.Diagnostics
Multiple items
type DllImportAttribute =
  inherit Attribute
  new : dllName:string -> DllImportAttribute
  val EntryPoint : string
  val CharSet : CharSet
  val SetLastError : bool
  val ExactSpelling : bool
  val PreserveSig : bool
  val CallingConvention : CallingConvention
  val BestFitMapping : bool
  val ThrowOnUnmappableChar : bool
  member Value : string

Full name: System.Runtime.InteropServices.DllImportAttribute

--------------------
DllImportAttribute(dllName: string) : unit
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val GetRunningObjectTable : reserved:uint32 * pprot:byref<IRunningObjectTable> -> int

Full name: vs10macros.GetRunningObjectTable
Multiple items
val uint32 : value:'T -> uint32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint32

--------------------
type uint32 = System.UInt32

Full name: Microsoft.FSharp.Core.uint32
val reserved : uint32
type IRunningObjectTable =
  member EnumRunning : ppenumMoniker:IEnumMoniker -> unit
  member GetObject : pmkObjectName:IMoniker * ppunkObject:obj -> int
  member GetTimeOfLastChange : pmkObjectName:IMoniker * pfiletime:FILETIME -> int
  member IsRunning : pmkObjectName:IMoniker -> int
  member NoteChangeTime : dwRegister:int * pfiletime:FILETIME -> unit
  member Register : grfFlags:int * punkObject:obj * pmkObjectName:IMoniker -> int
  member Revoke : dwRegister:int -> unit

Full name: System.Runtime.InteropServices.ComTypes.IRunningObjectTable
val pprot : byref<IRunningObjectTable>
val CreateBindCtx : reserved:uint32 * pctx:byref<IBindCtx> -> int

Full name: vs10macros.CreateBindCtx
type IBindCtx =
  member EnumObjectParam : ppenum:IEnumString -> unit
  member GetBindOptions : pbindopts:BIND_OPTS -> unit
  member GetObjectParam : pszKey:string * ppunk:obj -> unit
  member GetRunningObjectTable : pprot:IRunningObjectTable -> unit
  member RegisterObjectBound : punk:obj -> unit
  member RegisterObjectParam : pszKey:string * punk:obj -> unit
  member ReleaseBoundObjects : unit -> unit
  member RevokeObjectBound : punk:obj -> unit
  member RevokeObjectParam : pszKey:string -> int
  member SetBindOptions : pbindopts:BIND_OPTS -> unit

Full name: System.Runtime.InteropServices.ComTypes.IBindCtx
val pctx : byref<IBindCtx>
val getPidByWindowName : wn:string -> int

Full name: vs10macros.getPidByWindowName
val wn : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val dvproc : Process []
Multiple items
type Process =
  inherit Component
  new : unit -> Process
  member BasePriority : int
  member BeginErrorReadLine : unit -> unit
  member BeginOutputReadLine : unit -> unit
  member CancelErrorRead : unit -> unit
  member CancelOutputRead : unit -> unit
  member Close : unit -> unit
  member CloseMainWindow : unit -> bool
  member EnableRaisingEvents : bool with get, set
  member ExitCode : int
  ...

Full name: System.Diagnostics.Process

--------------------
Process() : unit
Process.GetProcessesByName(processName: string) : Process []
Process.GetProcessesByName(processName: string, machineName: string) : Process []
val p : Process option
module Array

from Microsoft.FSharp.Collections
val tryFind : predicate:('T -> bool) -> array:'T [] -> 'T option

Full name: Microsoft.FSharp.Collections.Array.tryFind
val px : Process
property Process.MainWindowTitle: string
System.String.ToLower() : string
System.String.ToLower(culture: System.Globalization.CultureInfo) : string
union case Option.Some: Value: 'T -> Option<'T>
val x : Process
property Process.Id: int
union case Option.None: Option<'T>
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val getDte : windowName:string -> 'a

Full name: vs10macros.getDte
val windowName : string
val mutable prot : IRunningObjectTable
val mutable pmonkenum : IEnumMoniker
type IEnumMoniker =
  member Clone : ppenum:IEnumMoniker -> unit
  member Next : celt:int * rgelt:IMoniker[] * pceltFetched:nativeint -> int
  member Reset : unit -> unit
  member Skip : celt:int -> int

Full name: System.Runtime.InteropServices.ComTypes.IEnumMoniker
val monikers : IMoniker []
type IMoniker =
  member BindToObject : pbc:IBindCtx * pmkToLeft:IMoniker * riidResult:Guid * ppvResult:obj -> unit
  member BindToStorage : pbc:IBindCtx * pmkToLeft:IMoniker * riid:Guid * ppvObj:obj -> unit
  member CommonPrefixWith : pmkOther:IMoniker * ppmkPrefix:IMoniker -> unit
  member ComposeWith : pmkRight:IMoniker * fOnlyIfNotGeneric:bool * ppmkComposite:IMoniker -> unit
  member Enum : fForward:bool * ppenumMoniker:IEnumMoniker -> unit
  member GetClassID : pClassID:Guid -> unit
  member GetDisplayName : pbc:IBindCtx * pmkToLeft:IMoniker * ppszDisplayName:string -> unit
  member GetSizeMax : pcbSize:int64 -> unit
  member GetTimeOfLastChange : pbc:IBindCtx * pmkToLeft:IMoniker * pFileTime:FILETIME -> unit
  member Hash : pdwHash:int -> unit
  ...

Full name: System.Runtime.InteropServices.ComTypes.IMoniker
val create : count:int -> value:'T -> 'T []

Full name: Microsoft.FSharp.Collections.Array.create
val pfeteched : nativeint
Multiple items
type IntPtr =
  struct
    new : value:int -> nativeint + 2 overloads
    member Equals : obj:obj -> bool
    member GetHashCode : unit -> int
    member ToInt32 : unit -> int
    member ToInt64 : unit -> int64
    member ToPointer : unit -> unit
    member ToString : unit -> string + 1 overload
    static val Zero : nativeint
    static member Add : pointer:nativeint * offset:int -> nativeint
    static member Size : int
    ...
  end

Full name: System.IntPtr

--------------------
System.IntPtr()
System.IntPtr(value: int) : unit
System.IntPtr(value: int64) : unit
System.IntPtr(value: nativeptr<unit>) : unit
field nativeint.Zero
val mutable ret : obj
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
val pid : int
val endpid : string
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
IRunningObjectTable.EnumRunning(ppenumMoniker: byref<IEnumMoniker>) : unit
IEnumMoniker.Reset() : unit
IEnumMoniker.Next(celt: int, rgelt: IMoniker [], pceltFetched: nativeint) : int
val mutable insname : string
val mutable pctx : IBindCtx
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
type Marshal =
  static val SystemDefaultCharSize : int
  static val SystemMaxDBCSCharSize : int
  static member AddRef : pUnk:nativeint -> int
  static member AllocCoTaskMem : cb:int -> nativeint
  static member AllocHGlobal : cb:nativeint -> nativeint + 1 overload
  static member AreComObjectsAvailableForCleanup : unit -> bool
  static member BindToMoniker : monikerName:string -> obj
  static member ChangeWrapperHandleStrength : otp:obj * fIsWeak:bool -> unit
  static member CleanupUnusedObjectsInCurrentContext : unit -> unit
  static member Copy : source:int[] * startIndex:int * destination:nativeint * length:int -> unit + 15 overloads
  ...

Full name: System.Runtime.InteropServices.Marshal
Marshal.ReleaseComObject(o: obj) : int
System.String.StartsWith(value: string) : bool
System.String.StartsWith(value: string, comparisonType: System.StringComparison) : bool
System.String.StartsWith(value: string, ignoreCase: bool, culture: System.Globalization.CultureInfo) : bool
System.String.EndsWith(value: string) : bool
System.String.EndsWith(value: string, comparisonType: System.StringComparison) : bool
System.String.EndsWith(value: string, ignoreCase: bool, culture: System.Globalization.CultureInfo) : bool
IRunningObjectTable.GetObject(pmkObjectName: IMoniker, ppunkObject: byref<obj>) : int
Raw view Test code New version

More information

Link:http://fssnip.net/68
Posted:12 years ago
Author:Eduardo Claudio
Tags: visual studio;dte;automation