You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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的问题。
    Create new project
  • 运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:15:05