Created
August 9, 2019 18:47
-
-
Save kevmal/0d5effd2ecfbd8289af52d9fb74f1c32 to your computer and use it in GitHub Desktop.
get the EnvDTE80.DTE2 object of the VS instance hosting the current fsi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//DTE object of VS hosting the FSI which runs this | |
//See: https://stackoverflow.com/questions/3102472/f-c-fsx-script-files-and-project-references/3102579#3102579 | |
//and: https://blogs.msdn.microsoft.com/kirillosenkov/2011/08/10/how-to-get-dte-from-visual-studio-process-id/ | |
#r "EnvDTE" | |
#r "EnvDTE80" | |
#r "VSLangProj" | |
open System | |
open System.Runtime.InteropServices | |
open System.Runtime.InteropServices.ComTypes | |
[<DllImport("ole32.dll")>] | |
extern int CreateBindCtx(uint32 reserved, IBindCtx& ppbc); | |
let objFromName cond = | |
let mutable bctx = null | |
let mutable rot = null | |
let mutable e = null | |
let m = Array.zeroCreate 1 | |
try | |
Marshal.ThrowExceptionForHR(CreateBindCtx(0u, &bctx)) | |
rot <- bctx.GetRunningObjectTable() | |
e <- rot.EnumRunning() | |
e.Reset() | |
let rec loop i = | |
if i >= m.Length || m.[i] = null then | |
if e.Next(m.Length, m, IntPtr.Zero) = 0 then | |
loop 0 | |
else | |
None | |
else | |
let n = | |
try | |
m.[i].GetDisplayName(bctx,null) | |
with | |
| _ -> null | |
if not(isNull n) && cond n then | |
let mutable robj = null | |
Marshal.ThrowExceptionForHR(rot.GetObject(m.[i], &robj)) | |
Some robj | |
else | |
m.[i] <- null | |
loop (i + 1) | |
loop 0 | |
finally | |
if not (isNull e) then Marshal.ReleaseComObject(e) |> ignore | |
if not (isNull rot) then Marshal.ReleaseComObject(rot) |> ignore | |
if not (isNull bctx) then Marshal.ReleaseComObject(bctx) |> ignore | |
let cline = System.Environment.CommandLine | |
let s = "--fsi-server:FSIChannel_" | |
let pidstr = cline.Substring(cline.IndexOf s + s.Length).Split([|'_'|],2).[0] | |
let pidpat = ":" + pidstr | |
let o = objFromName (fun x -> x.StartsWith "!VisualStudio.DTE." && x.EndsWith pidpat) |> Option.get :?> EnvDTE80.DTE2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment