Use PowerShell to create instance of COM object

2019-09-12 06:34发布

问题:

I'm trying to use SAP/BusinessObjects' Universe Design Tool (UDT) in a PowerShell session.

I registered the type library:

C:\> C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe "C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\designer.tlb

I attempted to create an instance of the Designer in PowerShell directly:

PS> $app = New-Object -ComObject Designer.Application
System.__ComObject

The instance doesn't have any of the expected properties and methods:

PS> $app | get-member

   TypeName: System.__ComObject

Name                      MemberType Definition
----                      ---------- ----------
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Equals                    Method     bool Equals(System.Object obj)
GetHashCode               Method     int GetHashCode()
GetLifetimeService        Method     System.Object GetLifetimeService()
GetType                   Method     type GetType()
InitializeLifetimeService Method     System.Object InitializeLifetimeService()
ToString                  Method     string ToString()

Next, I created a C# Cmdlet that wraps some of the Designer's functionality:

[System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommon.Open, "Universe")]
    [OutputType(typeof(Designer.Universe))]
    public class OpenUniverse  : System.Management.Automation.Cmdlet
    {

    Designer.Application application = null;

    [System.Management.Automation.Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
    [Alias("FullName")]
    public string[] Paths
    {
        get { return paths; }
        set { paths = value; }
    }
    private string[] paths;

    protected override void BeginProcessing()
    {
        application = new Application();
        application.Interactive = false;

        try
        {
          application.Logon("user", "password", "cluster", "secWinAd"); }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

    } # /BeginProcessing

    protected override void ProcessRecord()
    {
        Designer.Universe universe = null;

        try
        {
            foreach (string path in Paths)
            {
                universe = application.Universes.Open(path);
                WriteObject(universe);
            }

        }
        catch (System.Runtime.InteropServices.COMException e)
        {
          # ...
        }
        finally
        {
           if ( universe != null ) { universe.Close(); }
        }

    } # /ProcessRecord

} # / OpenUniverse

When run within a Visual Studio 2010 test, the code returns the expected object.

I created a manifest that references the assembly that was created by the project, then imported the module into a new PowerShell session.

PS> $unv = Open-Universe 'C:\Users\XXX\AppData\Roaming\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\Universes\Foo.unv'
PS> $unv
System.__ComObject

Is there a way to get PowerShell's reflection to generate the System.__ComObject instance's properties and methods?

回答1:

I'm not sure but in order PowerShell can display instance's properties and methods (late binding), the COM instance has to implement the ITypeInfo interface.