Getting the PowerShell::Create.AddScript.Invoke return value in c++

Viewed 56

With reference to Would like to run PowerShell code from inside a C++ program, I have created a program to execute the PowerShell script in C++ using System.Management.Automation.dll. But, I wasn't able to retrieve the return data from the Invoke() function. I can create individual PSObject, but I couldn't create the collection of PSObject.

Attached the the code:

#include <vcclr.h>
#include<Windows.h>
#include<iostream>
#using <mscorlib.dll>
#using <System.dll>
#include<vector>
#using <System.Management.Automation.dll>
using namespace std;

using namespace System;
using namespace System::Management::Automation;

void RunPowerShell( )
{
    Collection<PSObject> powObject= PowerShell::Create()->AddScript(gcnew String("get-wmiobject -query \"select * from win32_bios\""))->Invoke();
    PSObject k;
    
    String ^s=PowerShell::Create()->AddCommand("(Get-Variable PSVersionTable -ValueOnly).PSVersion")->ToString();
    printf("%s\n", s);
}
int main()
{
    RunPowerShell();
    return 0;
} 

Errors:

E0020 identifier "Collection" is undefined
E0254 type name is not allowed
E0020 identifier "powObject" is undefined
C2065 'Collection': undeclared identifier
C2275 'System::Management::Automation::PSObject': expected an expression instead of a type
C2065 'powObject': undeclared identifer
1 Answers

You need to either import the proper namespaces, like this:

#include <Windows.h>
#include <vcclr.h>
#include <iostream>
#include <vector>

#using <mscorlib.dll>
#using <System.dll>
#using <System.Management.Automation.dll>

using namespace std;
using namespace System;
using namespace System::Collections::ObjectModel; // you need this one
using namespace System::Management::Automation;

void RunPowerShell()
{
  // or simply use C++ auto!
  Collection<PSObject^>^ powObject = PowerShell::Create()->AddScript(gcnew String("get-wmiobject -query \"select * from win32_bios\""))->Invoke();

  for (int i = 0; i < powObject->Count; i++)
  {
    Console::WriteLine(powObject[i]);
  }
}

int main()
{
  RunPowerShell();
  return 0;

or just use the cool C++ auto keyword, like this:

auto powObject = PowerShell::Create()->AddScript(gcnew String("get-wmiobject -query \"select * from win32_bios\""))->Invoke();

And as a bonus, Visual Studio's magic will show the namespace for you if you hover the mouse around the auto keyword:

enter image description here

Related