Page 1 of 1

Spawning Powershell session from PCAN macro?

Posted: Mon 20. Mar 2017, 14:06
by lcaffrey
Hi,

I am trying to spawn a powershell program from PCAN VBScript. I have it working in windows VBScript but cannot get it working using the engine in PCAN Explorer. The motivation here is to pop up a dialog to the person creating the trace file so that they can save it to a named network location in a particular format, via a marco, without any user interaction other than selecting some parameters from dropdowns and list boxes.

Perhaps there is a better way to do this. I intended to force run the macro on exit so that the user would have to save the file to the correct location in the correct format.

Here is the listing for the Powershell. Let's call it

Code: Select all

Buttons.ps1

Code: Select all

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Select a Computer"
$objForm.Size = New-Object System.Drawing.Size(300,200) 
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
    {$global:x=$objListBox.SelectedItem;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
    {$objForm.Close()}})

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$global:x=$objListBox.SelectedItem;$objForm.Close()})
$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Please select a computer:"
$objForm.Controls.Add($objLabel) 

$objListBox = New-Object System.Windows.Forms.ListBox 
$objListBox.Location = New-Object System.Drawing.Size(10,40) 
$objListBox.Size = New-Object System.Drawing.Size(260,20) 
$objListBox.Height = 180

[void] $objListBox.Items.Add("atl-dc-001")
[void] $objListBox.Items.Add("atl-dc-002")
[void] $objListBox.Items.Add("atl-dc-003")
[void] $objListBox.Items.Add("atl-dc-004")
[void] $objListBox.Items.Add("atl-dc-005")
[void] $objListBox.Items.Add("atl-dc-006")
[void] $objListBox.Items.Add("atl-dc-007")

$objForm.Controls.Add($objListBox) 

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

Write-Host $x
Executing this on the Powershell command line works as expected.

Let's now invoke this Powershell from the DOS command line as a vbs. Let's call it

Code: Select all

GetFile.vbs

Code: Select all

engine = lcase(mid(WScript.FullName, InstrRev(Wscript.FullName, "\")+1))

if not engine = "cscript.exe" then
   MsgBox "launch with cscript.exe"
   Wscript.Quit
end if

pscommand = "K:\PcanTrace\Buttons.ps1"
cmd = "powershell.exe -noprofile -command " & pscommand
Set shell = CreateObject("WScript.Shell")
Set executor = shell.Exec(cmd)
executor.StdIn.Close
MsgBox executor.StdOut.ReadAll
This also works as expected. The idea is that Buttons.ps1 would return the full file name to the macro.

Converting this to a macro for PCAN Explorer...

Code: Select all

'FILE DESCRIPTION: Test and sample macros

Option Explicit

Sub TestPowershellExec()
'DESCRIPTION: Force save PCAN Trace file to network drive

Dim pscommand
Dim cmd
Dim Shell
Dim executor

pscommand = "K:\PcanTrace\Buttons.ps1"
cmd = "powershell.exe -noprofile -command " & pscommand
Set Shell = CreateObject("Shell.Application")
Set executor = Shell.Exec(cmd)
executor.StdIn.Close
MsgBox executor.StdOut.ReadAll

End Sub
PCAN-Explorer doesn't like this... giving an error "Line16: Object doesn't support this property or method Shell.Exec'"
I have also tried it this way...

Code: Select all

'FILE DESCRIPTION: Test and sample macros

Option Explicit

Sub TestPowershellExec()
'DESCRIPTION: Force save PCAN Trace file to network drive

Dim pscommand
Dim cmd
Dim Shell
Dim executor
Dim engine
'engine = lcase(mid(WScript.FullName, InstrRev(Wscript.FullName, "\")+1))
'MsgBox engine

pscommand = "K:\PcanTrace\Buttons.ps1"
cmd = "powershell.exe -noprofile -command " & pscommand
Set Shell = CreateObject("WScript.Shell")
Set executor = Shell.Exec(cmd)
executor.StdIn.Close
MsgBox executor.StdOut.ReadAll

End Sub
When I run it and PCAN offers to me to edit it, it seems to have automatically changed the WScript.Shell to Shell.Application. I read that perhaps Run rather than Exec might be a better way to do it but Run cannot pass a return value (i.e. filename) whereas Exec can. Run can write to a temp file which the macros could open but that sounds messy.

Code: Select all

'FILE DESCRIPTION: Test and sample macros

Option Explicit

Sub TestPowershellExec()
'DESCRIPTION: Force save PCAN Trace file to network drive

Dim pscommand
Dim cmd
Dim Shell
Dim executor

pscommand = "K:\PcanTrace\Buttons.ps1"
cmd = "powershell.exe -noprofile -command " & pscommand
Set Shell = CreateObject("Shell.Application")
Set executor = Shell.Exec(cmd)
executor.StdIn.Close
MsgBox executor.StdOut.ReadAll

End Sub
Same error...

Is it possible to do this? Any insights would be appreciated.

Regards

Liam

Re: Spawning Powershell session from PCAN macro?

Posted: Tue 21. Mar 2017, 12:02
by PEAK-Support
To run a PE 5 or PE6 code from the command shell, please see our samples that we ship with the product.
Open and study the LosslessTrace.vbs code, which runs from a shell a user interface to interact with the PCAN-Explorer.

In principial it works like this:

Code: Select all

' This VB-Script opens a project in PCAN-Explorer
'-----------------------------------------------------------------------------
' Copyright (c) 2017 PEAK-System Technik GmbH.  All rights reserved.

Dim app
Set app = CreateObject("PCANExplorer5.Application")

' Open the project
app.Documents.Open "$(MyDocsDir)\MyProject\MyProject.peproj"

' Show the application window
app.MainWindow.IsVisible = True
You ned to create a PE Object, and work with this based on the Object Model we have well documented in our Online Help file.

Re: Spawning Powershell session from PCAN macro?

Posted: Tue 21. Mar 2017, 13:09
by lcaffrey
I don't want to run PE5 code from the command shell.

I want to invoke Powershell from a PCAN macro (in a pem file) as described above.

I had a look again and figured out what the problem was. I needed to force powershell to set execution rights for the scope of the ps1 script invocation. This works now both with Run and with Exec. Problem solved!

Code: Select all

'FILE DESCRIPTION: Calling Powershell from VBS

Option Explicit

Sub TestPowershellExec()
'DESCRIPTION: Force save PCAN Trace file to network drive

Dim pscommand
Dim cmd
Dim Shell
Dim executor
Dim engine

pscommand = "K:\PcanTrace\Buttons.ps1"
cmd = "powershell.exe -noprofile -command Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force; " & pscommand
Set Shell = CreateObject("WScript.Shell")
Set executor = Shell.Exec(cmd)
'Shell.Run(cmd)
executor.StdIn.Close
MsgBox executor.StdOut.ReadAll

End Sub

Just wondering is there any other approach that you would consider using to present a dialog to a user from inside a PCAN session.

Thinking further here in relation to my approach... I wonder could I access the trace file from Powershell, or pass the trace file contents to Powershell. I could then use Powershell to save it directly to a location or endpoint. What do you think?

Thanks for your help.

Liam

Re: Spawning Powershell session from PCAN macro?

Posted: Tue 21. Mar 2017, 13:16
by PEAK-Support
We never work with PE5 or PE6 in this way. Normaly we wrote our own AddIns (in C#, VB.Net etc.) or we use the Software API to get more functions in our Application.

You could use the Trace file as it is and save it to a specified place (see also the script in the sample directory)
The Trace file format itself is open and could be found in the Forum as PDF file.