如何通过PowerShell 7向Visual Studio SSDT项目添加文件并处理COM对象识别问题
PowerShell 7操作Visual Studio 2019 SSDT项目时COM对象无法解析的问题
我想在PowerShell 7中实现向SSDT(数据库)项目自动添加/移除文件的功能,我的解决方案包含3个SSDT项目,运行在Visual Studio 2019实例中。
我参考了Stack Overflow上关于.NET Core替代System.Runtime.InteropServices.Marshal.GetActiveObject()的方案,搭配Nuget提供的EnvDTE、EnvDTE80、EnvDTE90、EnvDTE100 v16.10.31320.204库,已经可以获取到DTE对象。
但目前我遇到了大量无法解析的System.__ComObject对象,看起来还需要更多依赖库,但我不知道如何找到需要的对应库。
目前排查得到的信息如下:
> $dte Name : Microsoft Visual Studio FileName : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe Version : 16.0 CommandBars : System.__ComObject Windows : System.__ComObject Events : System.__ComObject AddIns : MainWindow : System.__ComObject ActiveWindow : System.__ComObject DisplayMode : 2 Solution : System.__ComObject Commands : System.__ComObject SelectedItems : System.__ComObject CommandLineArguments : "C:\Users\bgerhardi\source\Vega\VegaDW\src\VegaDW-DBs.sln" DTE : System.__ComObject LocaleID : 1033 WindowConfigurations : System.__ComObject Documents : System.__ComObject ActiveDocument : System.__ComObject Globals : System.__ComObject StatusBar : System.__ComObject FullName : C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe UserControl : True ObjectExtenders : System.__ComObject Find : System.__ComObject Mode : 1 ItemOperations : System.__ComObject UndoContext : System.__ComObject Macros : ActiveSolutionProjects : {} MacrosIDE : RegistryRoot : Software\Microsoft\VisualStudio\16.0_cd071aac Application : System.__ComObject ContextAttributes : System.__ComObject SourceControl : System.__ComObject SuppressUI : False Debugger : System.__ComObject Edition : Enterprise
查看$dte.Solution可以看到一个正常对象和另一组System.__ComObject对象:
> $dte.Solution System.__ComObject System.__ComObject System.__ComObject Name : Miscellaneous Files FileName : IsDirty : False Collection : DTE : System.__ComObject Kind : {66A2671D-8FB5-11D2-AA7E-00C04F688DDE} ProjectItems : System.__ComObject Properties : UniqueName : <MiscFiles> Object : ExtenderNames : {} ExtenderCATID : {610d4612-d0d5-11d2-8599-006097c68e81} FullName : Saved : True ConfigurationManager : Globals : ParentProjectItem : CodeModel :
但是我在Visual Studio UI中看不到这个Miscellaneous Files项。
当我尝试访问这些对象时,索引0不存在,剩下的都是无法解析的System.__ComObject:
> $dte.Solution[0] OperationStopped: Value does not fall within the expected range. > $dte.Solution[1] System.__ComObject > $dte.Solution[1] | gm >
我尝试将对象强转为多种类型,都报错提示存在无法在注册表或互联网上查到的COM GUID:
> [EnvDTE.Project]$dte.Solution[1] InvalidArgument: Cannot convert the "System.__ComObject" value of type "System.__ComObject#{2aa7b615-65c8-356e-8652-98f68ab7548e}" to type "EnvDTE.Project".
请问我该用什么正确方法遍历这些__ComObject,找到我需要的对应类型?
问题复现步骤
- 在Visual Studio 2019中新建一个"SQL Server Database Project",该场景下也会出现同样的无法解析
System.__ComObject的问题。
- 运行PS7实例
- 执行以下代码:
$methoddef = 'public static object GetActiveObject(string progId, bool throwOnError = false) { if (progId == null) throw new ArgumentNullException(nameof(progId)); var hr = CLSIDFromProgIDEx(progId, out var clsid); if (hr < 0) { if (throwOnError) Marshal.ThrowExceptionForHR(hr); return null; } hr = GetActiveObject(clsid, IntPtr.Zero, out var obj); if (hr < 0) { if (throwOnError) Marshal.ThrowExceptionForHR(hr); return null; } return obj; } [DllImport("ole32")] private static extern int CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid lpclsid); [DllImport("oleaut32")] private static extern int GetActiveObject([MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, IntPtr pvReserved, [MarshalAs(UnmanagedType.IUnknown)] out object ppunk);' $blah = add-type -MemberDefinition $methoddef -Name "Blah" -Namespace "Blah" -PassThru $dte = $blah::GetActiveObject('VisualStudio.DTE.16.0')
- 可以发现
$dte.ActiveSolutionProjects[0]不会返回有效内容,仅返回System.__ComObject
内容的提问来源于stack exchange,提问作者Brett
相关产品推荐
相关产品推荐

