private object GetDteObject(IRunningObjectTable rot, IMoniker moniker) { object dteObject; int hr = rot.GetObject(moniker, out dteObject); if (ErrorHandler.Failed(hr)) { ErrorHandler.ThrowOnFailure(hr, null); } return dteObject; }
private static void InitializeSolidWorks() { string monikerName = "SolidWorks_PID_"; object app; IBindCtx context = null; IRunningObjectTable rot = null; IEnumMoniker monikers = null; try { CreateBindCtx(0, out context); context.GetRunningObjectTable(out rot); rot.EnumRunning(out monikers); IMoniker[] moniker = new IMoniker[1]; while (monikers.Next(1, moniker, IntPtr.Zero) == 0) { var curMoniker = moniker.First(); string name = null; if (curMoniker != null) { try { curMoniker.GetDisplayName(context, null, out name); } catch (UnauthorizedAccessException ex) { MessageBox.Show("Failed to get SolidWorks_PID." + "\t" + ex); } } if (name.Contains(monikerName)) { rot.GetObject(curMoniker, out app); swApp = (SldWorks)app; swApp.Visible = true; return; } } string progId = "SldWorks.Application"; Type progType = Type.GetTypeFromProgID(progId); app = Activator.CreateInstance(progType) as SldWorks; swApp = (SldWorks)app; swApp.Visible = true; return; } finally { if (monikers != null) { Marshal.ReleaseComObject(monikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (context != null) { Marshal.ReleaseComObject(context); } } }
private EnvDTE.DTE GetDevToolsEnvironment(int processId) { object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); var moniker = new IMoniker[1]; var numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { var runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to } var monikerRegex = new Regex(@"!VisualStudio.DTE\.\d+\.\d+\:" + processId, RegexOptions.IgnoreCase); if (!string.IsNullOrEmpty(name) && monikerRegex.IsMatch(name)) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return(runningObject as EnvDTE.DTE); }
private static ISldWorks GetSwAppFromProcess(int processId) { var monikerName = "SolidWorks_PID_" + processId.ToString(); IBindCtx context = null; IRunningObjectTable rot = null; IEnumMoniker monikers = null; try { CreateBindCtx(0, out context); context.GetRunningObjectTable(out rot); rot.EnumRunning(out monikers); var moniker = new IMoniker[1]; while (monikers.Next(1, moniker, IntPtr.Zero) == 0) { var curMoniker = moniker.First(); string name = null; if (curMoniker != null) { try { curMoniker.GetDisplayName(context, null, out name); } catch (UnauthorizedAccessException) { } } if (string.Equals(monikerName, name, StringComparison.CurrentCultureIgnoreCase)) { object app; rot.GetObject(curMoniker, out app); return(app as ISldWorks); } } } finally { if (monikers != null) { Marshal.ReleaseComObject(monikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (context != null) { Marshal.ReleaseComObject(context); } } return(null); }
private static DTE GetDTE(int processId) { #if DEV15 // VS 2017 doesn't install some assemblies to the GAC that are needed to work with the // debugger, and as the tests don't execute in the devenv.exe process, those assemblies // fail to load - so load them manually from PublicAssemblies. // Use the executable name, as this is only needed for the out of proc test execution // that may interact with the debugger (vstest.executionengine.x86.exe). if (!DTELoaded) { var currentProc = Process.GetCurrentProcess().MainModule.FileName; if (StringComparer.OrdinalIgnoreCase.Equals( Path.GetFileName(currentProc), "vstest.executionengine.x86.exe")) { var baseDir = Path.GetDirectoryName(currentProc); var publicAssemblies = Path.Combine(baseDir, "..\\..\\..\\PublicAssemblies"); Assembly.LoadFrom(Path.Combine(publicAssemblies, "Microsoft.VisualStudio.OLE.Interop.dll")); Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte90.dll")); Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte80.dll")); Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte.dll")); } DTELoaded = true; } #endif MessageFilter.Register(); var prefix = Process.GetProcessById(processId).ProcessName; if ("devenv".Equals(prefix, StringComparison.OrdinalIgnoreCase)) { prefix = "VisualStudio"; } var progId = $"!{prefix}.DTE.15.0:{processId}"; object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); var moniker = new IMoniker[1]; uint numberFetched = 0; while (enumMonikers.Next(1, moniker, out numberFetched) == 0) { var runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (StringComparer.Ordinal.Equals(name, progId)) { rot.GetObject(runningObjectMoniker, out runningObject); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return((DTE)runningObject); }
public static object GetInstanceFromROT(RunningObjectTableComponentInfo RunningComponent) { IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; object ResultInstance = null; try { // query table and returns null if no objects runnings if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) return null; // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // create binding object IBindCtx bindInfo; CreateBindCtx(0, out bindInfo); // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); string ppszDisplayName; try { monikerContainer[0].GetDisplayName(bindInfo, null, out ppszDisplayName); } catch { ppszDisplayName = ""; } Guid pClassID; try { monikerContainer[0].GetClassID(out pClassID); } catch { pClassID = Guid.Empty; } string ClassName; try { ClassName = TypeDescriptor.GetClassName(comInstance); } catch { ClassName = ""; } string ComponentName; try { ComponentName = TypeDescriptor.GetComponentName(comInstance, false); } catch { ComponentName = ""; } if ((RunningComponent.DisplayName == ppszDisplayName) && (RunningComponent.ClsID == pClassID) && (RunningComponent.ComponentClassName == ClassName) && (RunningComponent.ComponentName == ComponentName) ) { Marshal.ReleaseComObject(bindInfo); ResultInstance = comInstance; } else Marshal.ReleaseComObject(comInstance); Marshal.ReleaseComObject(bindInfo); } return ResultInstance; } finally { // release proxies if (runningObjectTable != null) Marshal.ReleaseComObject(runningObjectTable); if (monikerList != null) Marshal.ReleaseComObject(monikerList); } }
/// <summary> /// Returns all running com proxies from the running object table there matched with the input parameters /// WARNING: the method returns always the first com proxy from the running object table if multiple (match) proxies exists. /// </summary> /// <param name="componentName">component name, for example Excel, null is a wildcard </param> /// <param name="className">class name, for example Application, null is a wildcard </param> /// <returns>COM proxy enumerator</returns> public static IDisposableEnumeration GetActiveProxies(string componentName, string className) { IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; Misc.DisposableObjectList resultList = new Misc.DisposableObjectList(); try { // query table and returns null if no objects running if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) { return(null); } // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); if (null == comInstance) { continue; } // get class name and component name string name = TypeDescriptor.GetClassName(comInstance); string component = TypeDescriptor.GetComponentName(comInstance, false); // match for equal and add to list bool componentNameEqual = String.IsNullOrWhiteSpace(component) ? true : (componentName.Equals(component, StringComparison.InvariantCultureIgnoreCase)); bool classNameEqual = String.IsNullOrWhiteSpace(className) ? true : (className.Equals(name, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { resultList.Add(comInstance); } else { componentNameEqual = ((_ballmersPlace + componentName).Equals(component, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { resultList.Add(comInstance); } else { if (comInstance.GetType().IsCOMObject) { Marshal.ReleaseComObject(comInstance); } } } } return(resultList); } catch (Exception exception) { DebugConsole.Default.WriteException(exception); throw; } finally { // release proxies if (runningObjectTable != null) { Marshal.ReleaseComObject(runningObjectTable); } if (monikerList != null) { Marshal.ReleaseComObject(monikerList); } } }
private static object GetDTE(int processId) { object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; var names = new List <string>(); try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; IntPtr numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } names.Add(name); if (!string.IsNullOrEmpty(name) && name.StartsWith("!VisualStudio.DTE.") && name.EndsWith(processId.ToString())) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return(runningObject); }
internal static DTE2 GetDTE() { string progId = @"^!VisualStudio\.DTE\.\d{2}\.\d\:" + System.Diagnostics.Process.GetCurrentProcess().Id + "$"; object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; IntPtr numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (!string.IsNullOrEmpty(name) && Regex.IsMatch(name, progId)) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return((DTE2)runningObject); }
public static TComObj TryGetComObjectByMonikerName <TComObj>(string monikerName) { IBindCtx context = null; IRunningObjectTable rot = null; IEnumMoniker monikers = null; try { CreateBindCtx(0, out context); context.GetRunningObjectTable(out rot); rot.EnumRunning(out monikers); var moniker = new IMoniker[1]; while (monikers.Next(1, moniker, IntPtr.Zero) == 0) { var curMoniker = moniker.First(); string name = null; if (curMoniker != null) { try { curMoniker.GetDisplayName(context, null, out name); } catch (UnauthorizedAccessException) { } } if (string.Equals(monikerName, name, StringComparison.CurrentCultureIgnoreCase)) { object app; rot.GetObject(curMoniker, out app); return((TComObj)app); } } } finally { if (monikers != null) { Marshal.ReleaseComObject(monikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (context != null) { Marshal.ReleaseComObject(context); } } return(default(TComObj)); }
// Test this // http://adndevblog.typepad.com/autocad/2013/12/accessing-com-applications-from-the-running-object-table.html public static object GetRunningInstance(string progId) { // get the app clsid string clsId = string.Empty; Type type = Type.GetTypeFromProgID(progId); if (type != null) { clsId = type.GUID.ToString().ToUpper(); } // get Running Object Table IRunningObjectTable Rot = null; GetRunningObjectTable(0, out Rot); if (Rot == null) { return(null); } // get enumerator for ROT entries IEnumMoniker monikerEnumerator = null; Rot.EnumRunning(out monikerEnumerator); if (monikerEnumerator == null) { return(null); } monikerEnumerator.Reset(); object instance = null; IntPtr pNumFetched = new IntPtr(); IMoniker[] monikers = new IMoniker[1]; while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0) { IBindCtx bindCtx; CreateBindCtx(0, out bindCtx); if (bindCtx == null) { continue; } string displayName; monikers[0].GetDisplayName(bindCtx, null, out displayName); if (displayName.ToUpper().IndexOf(clsId) > 0) { object ComObject; Rot.GetObject(monikers[0], out ComObject); if (ComObject == null) { continue; } instance = ComObject; break; } } return(instance); }
/// <summary> /// 从 ROT 中获取 SolidWorks 程序 /// </summary> /// <param name="processId">进程 id</param> /// <returns>SldWorks</returns> private SldWorks GetSolidWorksFromProcess(int processId) { // 进程名字 string monikerName = "SolidWorks_PID_" + processId.ToString(); // 绑定上下文 IBindCtx context = null; // 运行时对象表 Running Object Table IRunningObjectTable rot = null; // 运行时对象名称集合 IEnumMoniker monikers = null; try { // 创建绑定上下文 CreateBindCtx(0, out context); // 获取运行时对象表 Running Object Table context.GetRunningObjectTable(out rot); // 列出运行时对象名称 rot.EnumRunning(out monikers); // IMoniker[] moniker = new IMoniker[1]; while (monikers.Next(1, moniker, IntPtr.Zero) == 0) { // 当前名字 IMoniker curMoniker = moniker.First(); // 显示名称 string name = null; if (curMoniker != null) { try { // 获取显示名称 curMoniker.GetDisplayName(context, null, out name); } catch (UnauthorizedAccessException) { } } if (string.Equals(monikerName, name, StringComparison.CurrentCultureIgnoreCase)) { // 从ROT获取对象并返回 rot.GetObject(curMoniker, out object app); SldWorks sldWorks = app as SldWorks; // 这一句不起作用 sldWorks.Visible = false; return(sldWorks); } } } finally { if (monikers != null) { Marshal.ReleaseComObject(monikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (context != null) { Marshal.ReleaseComObject(context); } } return(null); }
/// <summary> /// returns a running com proxy from the running object table. the method takes the first proxy there matched with the input parameters. /// WARNING: the method returns always the first com proxy from the running object table if multiple (match) proxies exists. /// </summary> /// <param name="componentName">component name, for example Excel</param> /// <param name="className">class name, for example Application</param> /// <param name="throwOnError">throw an exception if no proxy was found</param> /// <returns>a native COM proxy</returns> public static object GetActiveProxyFromROT(string componentName, string className, bool throwOnError) { if (String.IsNullOrEmpty(componentName)) { throw new ArgumentNullException("componentName"); } if (String.IsNullOrEmpty(className)) { throw new ArgumentNullException("className"); } IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; try { // query table and returns null if no objects runnings if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) { return(null); } // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); // get class name and component name string name = TypeDescriptor.GetClassName(comInstance); string component = TypeDescriptor.GetComponentName(comInstance, false); // match for equal and return bool componentNameEqual = (componentName.Equals(component, StringComparison.InvariantCultureIgnoreCase)); bool classNameEqual = (className.Equals(name, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { return(comInstance); } else { componentNameEqual = ((_ballmersPlace + componentName).Equals(component, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { return(comInstance); } else { if (comInstance.GetType().IsCOMObject) { Marshal.ReleaseComObject(comInstance); } } } } if (throwOnError) { throw new COMException("Target instance is not running."); } else { return(null); } } catch (Exception exception) { DebugConsole.Default.WriteException(exception); throw; } finally { // release proxies if (runningObjectTable != null) { Marshal.ReleaseComObject(runningObjectTable); } if (monikerList != null) { Marshal.ReleaseComObject(monikerList); } } }
/// <summary> /// Returns all running com proxies + add. informations from the running object table there matched with the input parameters /// WARNING: the method returns always the first com proxy from the running object table if multiple (match) proxies exists. /// </summary> /// <returns>IDisposableEnumeration with proxy informations</returns> public static IDisposableEnumeration <ProxyInformation> GetActiveProxyInformations() { IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; RunningObjectTableItemCollection resultList = new RunningObjectTableItemCollection(); try { // query table and returns null if no objects running if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) { return(null); } // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); if (null == comInstance) { continue; } string name = TypeDescriptor.GetClassName(comInstance); string component = TypeDescriptor.GetComponentName(comInstance, false); IBindCtx bindInfo = null; string displayName = String.Empty; Guid classID = Guid.Empty; if (CreateBindCtx(0, out bindInfo) == 0) { monikerContainer[0].GetDisplayName(bindInfo, null, out displayName); monikerContainer[0].GetClassID(out classID); Marshal.ReleaseComObject(bindInfo); } string itemClassName = TypeDescriptor.GetClassName(comInstance); string itemComponentName = TypeDescriptor.GetComponentName(comInstance); COMTypes.ITypeInfo typeInfo = null; string itemLibrary = String.Empty; if (classID != Guid.Empty) { typeInfo = TryCreateTypeInfo(comInstance); itemLibrary = null != typeInfo?GetParentLibraryGuid(typeInfo).ToString() : String.Empty; } string itemID = classID != Guid.Empty ? classID.ToString() : String.Empty; ProxyInformation entry = new ProxyInformation(comInstance, displayName, itemID, itemClassName, itemComponentName, itemLibrary, IntPtr.Zero, ProxyInformation.ProcessElevation.Unknown); resultList.Add(entry); if (classID != Guid.Empty && typeInfo != null) { ReleaseTypeInfo(typeInfo); } } return(resultList); } catch (Exception exception) { DebugConsole.Default.WriteException(exception); throw; } finally { // release proxies if (runningObjectTable != null) { Marshal.ReleaseComObject(runningObjectTable); } if (monikerList != null) { Marshal.ReleaseComObject(monikerList); } } }
public static DTE GetDTE(int processId) { object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; IntPtr numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (!string.IsNullOrEmpty(name) && Regex.Match(name, "VisualStudio.*" + processId).Success) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return((DTE)runningObject); }
private static DTE GetDTE(int processId) { MessageFilter.Register(); var prefix = Process.GetProcessById(processId).ProcessName; if ("devenv".Equals(prefix, StringComparison.OrdinalIgnoreCase)) { prefix = "VisualStudio"; } string progId = string.Format("!{0}.DTE.{1}:{2}", prefix, AssemblyVersionInfo.VSVersion, processId); object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; uint numberFetched = 0; while (enumMonikers.Next(1, moniker, out numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { if (runningObjectMoniker != null) { runningObjectMoniker.GetDisplayName(bindCtx, null, out name); } } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal)) { rot.GetObject(runningObjectMoniker, out runningObject); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return((DTE)runningObject); }
/// <summary> /// Get a COM handle to DTE of a running VS instance /// </summary> /// <param name="vsVersion">Version of Visual Studio (15.0 for 2017)</param> /// <param name="processId">Process ID of the running version</param> /// <returns></returns> public static DTE GetDTE(string vsVersion, int processId) { //var vsRunningInstance = BoundInstances.FirstOrDefault(x => x.ProcessId == processId && x.Version == vsVersion); //if (vsRunningInstance != null) //{ // return vsRunningInstance.VsInstance; //} string progId = $"!VisualStudio.DTE.{vsVersion}:{processId.ToString()}"; object runningObject = null; IBindCtx bindCtx = null; IRunningObjectTable rot = null; IEnumMoniker enumMonikers = null; try { Marshal.ThrowExceptionForHR(WinApiProxy.CreateBindCtx(reserved: 0, ppbc: out bindCtx)); bindCtx.GetRunningObjectTable(out rot); rot.EnumRunning(out enumMonikers); IMoniker[] moniker = new IMoniker[1]; IntPtr numberFetched = IntPtr.Zero; while (enumMonikers.Next(1, moniker, numberFetched) == 0) { IMoniker runningObjectMoniker = moniker[0]; string name = null; try { runningObjectMoniker?.GetDisplayName(bindCtx, null, out name); Debug.WriteLine($"Name = {name}"); } catch (UnauthorizedAccessException) { // Do nothing, there is something in the ROT that we do not have access to. } if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal)) { Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject)); break; } } } finally { if (enumMonikers != null) { Marshal.ReleaseComObject(enumMonikers); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bindCtx != null) { Marshal.ReleaseComObject(bindCtx); } } return((DTE)runningObject); }
/// <summary> /// Visual Studioデバッガーにアタッチします。 /// </summary> /// <param name="debuggerInfo">現在のプロセスをアタッチするデバッガー情報。</param> /// <returns><paramref name="debuggerInfo" />がVisual Studioのデバッガー情報で、アタッチに成功した場合は<c>True</c>。その他の場合は<c>False</c>。</returns> public override bool AttachToType(DebuggerInfo debuggerInfo) { if (debuggerInfo == null || debuggerInfo.DebuggerType != typeof(VisualStudioDebuggerInfoProvider) || !(debuggerInfo.ProcessId > 0)) { return(false); } IBindCtx bc = null; IRunningObjectTable rot = null; IEnumMoniker enumMoniker = null; try { var r = NativeMethods.CreateBindCtx(0, out bc); Marshal.ThrowExceptionForHR(r); if (bc == null) { throw new Win32Exception(); } bc.GetRunningObjectTable(out rot); if (rot == null) { throw new Win32Exception(); } rot.EnumRunning(out enumMoniker); if (enumMoniker == null) { throw new Win32Exception(); } var cp = Process.GetCurrentProcess().Id; var dteSuffix = ":" + debuggerInfo.ProcessId; var moniker = new IMoniker[1]; while (enumMoniker.Next(1, moniker, IntPtr.Zero) == 0 && moniker[0] != null) { string dn; moniker[0].GetDisplayName(bc, null, out dn); if (dn.StartsWith("!VisualStudio.DTE.") && dn.EndsWith(dteSuffix)) { object dte, dbg, lps; rot.GetObject(moniker[0], out dte); for (var i = 0; i < 10; i++) { try { dbg = dte.GetType().InvokeMember("Debugger", BindingFlags.GetProperty, null, dte, null); lps = dbg.GetType().InvokeMember("LocalProcesses", BindingFlags.GetProperty, null, dbg, null); var lpn = (System.Collections.IEnumerator)lps.GetType().InvokeMember("GetEnumerator", BindingFlags.InvokeMethod, null, lps, null); while (lpn.MoveNext()) { var pn = Convert.ToInt32(lpn.Current.GetType().InvokeMember("ProcessID", BindingFlags.GetProperty, null, lpn.Current, null)); if (pn == cp) { lpn.Current.GetType().InvokeMember("Attach", BindingFlags.InvokeMethod, null, lpn.Current, null); return(true); } } } catch (COMException) { Thread.Sleep(250); } } Marshal.ReleaseComObject(moniker[0]); break; } Marshal.ReleaseComObject(moniker[0]); } return(false); } finally { if (enumMoniker != null) { Marshal.ReleaseComObject(enumMoniker); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bc != null) { Marshal.ReleaseComObject(bc); } } }
public static List<RunningObjectTableComponentInfo> GetComponentsFromROT() { IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; List<RunningObjectTableComponentInfo> resultList = new List<RunningObjectTableComponentInfo>(); try { // query table and returns null if no objects runnings if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) return null; // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // create binding object IBindCtx bindInfo; CreateBindCtx(0, out bindInfo); // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); string ppszDisplayName; try { monikerContainer[0].GetDisplayName(bindInfo, null, out ppszDisplayName); } catch { ppszDisplayName = ""; } Guid pClassID; try { monikerContainer[0].GetClassID(out pClassID); } catch { pClassID = Guid.Empty; } System.Runtime.InteropServices.ComTypes.FILETIME pLastChangedFileTime; try { runningObjectTable.GetTimeOfLastChange(monikerContainer[0], out pLastChangedFileTime);} catch { pLastChangedFileTime = new System.Runtime.InteropServices.ComTypes.FILETIME(); } long pcbSize; try { monikerContainer[0].GetSizeMax(out pcbSize);} catch { pcbSize = 0;} Boolean IsDirty; try {IsDirty = (monikerContainer[0].IsDirty() == 0); } catch {IsDirty = false;} Boolean IsRunning; try {IsRunning = (runningObjectTable.IsRunning(monikerContainer[0]) == 0); } catch {IsRunning = false;} // creating the unbound object to hold the Data out of the current component IMoniker RunningObjectTableComponentInfo ROTComponent = new RunningObjectTableComponentInfo( ppszDisplayName, pClassID, ConvertFromFILETIME(pLastChangedFileTime), pcbSize, TypeDescriptor.GetComponentName(comInstance, false), TypeDescriptor.GetClassName(comInstance), IsRunning, IsDirty ); resultList.Add(ROTComponent); // clean up and release object Marshal.ReleaseComObject(comInstance); Marshal.ReleaseComObject(bindInfo); } // not running return resultList; } finally { // release proxies if (runningObjectTable != null) Marshal.ReleaseComObject(runningObjectTable); if (monikerList != null) Marshal.ReleaseComObject(monikerList); } }
/// <summary> /// returns all running com proxies from the running object table there matched with the input parameters /// </summary> /// <param name="componentName">component name, for example Excel</param> /// <param name="className">class name, for example Application</param> /// <returns>COM proxy list</returns> public static List <object> GetActiveProxiesFromROT(string componentName, string className) { IEnumMoniker monikerList = null; IRunningObjectTable runningObjectTable = null; List <object> resultList = new List <object>(); try { // query table and returns null if no objects runnings if (GetRunningObjectTable(0, out runningObjectTable) != 0 || runningObjectTable == null) { return(null); } // query moniker & reset runningObjectTable.EnumRunning(out monikerList); monikerList.Reset(); IMoniker[] monikerContainer = new IMoniker[1]; IntPtr pointerFetchedMonikers = IntPtr.Zero; // fetch all moniker while (monikerList.Next(1, monikerContainer, pointerFetchedMonikers) == 0) { // create binding object IBindCtx bindInfo; CreateBindCtx(0, out bindInfo); // query com proxy info object comInstance = null; runningObjectTable.GetObject(monikerContainer[0], out comInstance); // get class name and component name string name = TypeDescriptor.GetClassName(comInstance); string component = TypeDescriptor.GetComponentName(comInstance, false); // match for equal and add to list bool componentNameEqual = (componentName.Equals(component, StringComparison.InvariantCultureIgnoreCase)); bool classNameEqual = (className.Equals(name, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { resultList.Add(comInstance); } else { componentNameEqual = ((_ballmersPlace + componentName).Equals(component, StringComparison.InvariantCultureIgnoreCase)); if (componentNameEqual && classNameEqual) { resultList.Add(comInstance); } else { if (comInstance.GetType().IsCOMObject) { Marshal.ReleaseComObject(comInstance); } } } if (bindInfo.GetType().IsCOMObject) { Marshal.ReleaseComObject(bindInfo); } } return(resultList); } finally { // release proxies if (runningObjectTable != null) { Marshal.ReleaseComObject(runningObjectTable); } if (monikerList != null) { Marshal.ReleaseComObject(monikerList); } } }