Generate and run PowerShell scripts dynamically
In my prior post Use new XML Features of VB to generate dynamic scripts and text files , we generated a simple batch file. It’s difficult to modify the registry or manipulate a COM object
PowerShell scripts allow you to manipulate files, registry and COM objects, using a uniform object manipulation metaphor. For example, you can use CD and DIR at a command prompt to navigate the file system, the registry and certificate store too.
Here's a simple sample navigating the registry of Fox: (user typed text in this color)
Windows PowerShell
Copyright (C) 2006 Microsoft Corporation. All rights reserved.
PS C:\Documents and Settings\calvinh> cd hkcu:
PS HKCU:\> cd Software
PS HKCU:\Software> cd HKCU:\Software\Microsoft\VisualFoxPro
PS HKCU:\Software\Microsoft\VisualFoxPro> dir
Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualFoxPro
SKC VC Name Property
--- -- ---- --------
5 0 9.0 {}
PS HKCU:\Software\Microsoft\VisualFoxPro> cd 9.0
PS HKCU:\Software\Microsoft\VisualFoxPro\9.0> dir
Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualFoxPro\9.0
SKC VC Name Property
--- -- ---- --------
0 1 ChooseColor {(default)}
0 8 Coverage {FrmzoomHeight, FrmzoomTop, FrmzoomWidth, FrmzoomLeft...}
0 7 Desktop {Zoomed, Row, Column, Height...}
0 0 Fonts {}
4 192 Options {LastProject, TALK, StatusBar, NOTIFY...}
PS HKCU:\Software\Microsoft\VisualFoxPro\9.0>
This PowerShell script sample modifies the setting of SET SAFETY by directly manipulating the registry, then forcing VFP to reread the registry settings using SYS(3056)
ERASE d:\t.txt
*https://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx
*Set-ExecutionPolicy remotesigned
SET SAFETY OFF
?"Safety before",SET("Safety")
TEXT TO myvar
#This is a sample powershell script
#get-process > d:\t.txt
#get-psdrive > d:\t.txt
#CD HKCU:\Software\Microsoft\VisualFoxPro\9.0
#get-Item * >> d:\t.txt
#can specify path to registry
#get setting of all reg keys starting with "s":
#get-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options s* >> d:\t.txt
#get-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options safety >> d:\t.txt
set-ItemProperty -path registry::HKCU\Software\Microsoft\VisualFoxPro\9.0\Options safety ON >> d:\t.txt
ENDTEXT
STRTOFILE(myvar,"d:\Myscript.ps1")
! powershell d:\Myscript
?STRCONV(SUBSTR(FILETOSTR("d:\t.txt"),3),6) && convert from Unicode, remove ByteOrderMark
SYS(3056) && Force VFP to reread registry
?"Safety After: ",SET("safety")
SET SAFETY OFF && restore value
You can even create a VFP COM Object from within a PowerShell script and invoke its methods: (using my favorite VFP COM Object "t1.c1")
Here's a PowerShell script sample that creates an instance of Excel, and passes it to the VFP COM object for further manipulation: The hardest part of this code was trying to figure out how to close Excel without saving changes!
PowerShell variables start with “$”, comments start with “#”
SET SAFETY OFF
sOutputFile="d:\t.txt"
ERASE (sOutputFile)
ERASE (sOutputFile)
TEXT TO myvar TEXTMERGE
#create Excel
$oExcel = New-Object -ComObject Excel.Application
#create VFP COM Object
$oVFP = New-Object -ComObject t1.c1
#Pass Excel to VFP object
$oVFP.MyDoCmd("p2.Visible=1",$oExcel,0,0,0)
#Get the name of the object
$oVFP.MyEval("p2.name",$oExcel,0,0,0) >> <<sOutputFile>>
#Add a workbook
$oVFP.MyDoCmd("p2.Workbooks.Add",$oExcel,0,0,0)
$pv="PowerShell variable"
#Change the 1st cell's value to a combination of VFP and Powershell vars
$oVFP.MyDoCmd("p2.Cells(1,1).value='Hi from VFP '+p3",$oExcel,$pv,0,0)
$oVFP.MyDoCmd("DECLARE integer MessageBoxA IN WIN32API integer,string,string,integer",0,0,0,0)
$oVFP.MyEval("MessageBoxA(0,'Hi From VFP inside PowerShell','',0)",0,0,0,0)
#Close Excel workbook without saving!
$oVFP.MyDoCmd("p2.ActiveWorkbook.Close(.f.)",$oExcel,0,0,0)
$oVFP.MyDoCmd("p2.Visible=0",$oExcel,0,0,0)
$oVFP.MyDoCmd("p2.Quit",$oExcel,0,0,0)
ENDTEXT
STRTOFILE(myvar,"d:\Myscript.ps1")
! powershell d:\Myscript
IF FILE(sOutputFile)
?STRCONV(SUBSTR(FILETOSTR(sOutputFile),3),6) && convert from Unicode, remove ByteOrderMark
ENDIF
You can do this from VB using the new XML features (Use new XML Features of VB to generate dynamic scripts and text files )
Module Module1
Sub Main()
Dim sOutputFile = "d:\t.txt"
Dim sScriptFile = "d:\t.ps1"
If My.Computer.FileSystem.FileExists(sOutputFile) Then
My.Computer.FileSystem.DeleteFile(sOutputFile)
End If
Dim PowerShellScriptXML = <myxml>
#create Excel
$oExcel = New-Object -ComObject Excel.Application
#create VFP COM Object
$oVFP = New-Object -ComObject t1.c1
#Pass Excel to VFP object
$oVFP.MyDoCmd("p2.Visible=1",$oExcel,0,0,0)
#Get the name of the object
$oVFP.MyEval("p2.name",$oExcel,0,0,0) >> <%= sOutputFile %>
#Add a workbook
$oVFP.MyDoCmd("p2.Workbooks.Add",$oExcel,0,0,0)
$pv="PowerShell variable"
#Change the 1st cell's value to a combination of VFP and Powershell vars
$oVFP.MyDoCmd("p2.Cells(1,1).value='Hi from VFP '+p3",$oExcel,$pv,0,0)
$oVFP.MyDoCmd("DECLARE integer MessageBoxA IN WIN32API integer,string,string,integer",0,0,0,0)
$oVFP.MyEval("MessageBoxA(0,'Hi From VFP inside PowerShell','',0)",0,0,0,0)
#Close Excel workbook without saving!
$oVFP.MyDoCmd("p2.ActiveWorkbook.Close(.f.)",$oExcel,0,0,0)
$oVFP.MyDoCmd("p2.Visible=0",$oExcel,0,0,0)
$oVFP.MyDoCmd("p2.Quit",$oExcel,0,0,0)
</myxml>
Console.WriteLine(PowerShellScriptXML.Value)
My.Computer.FileSystem.WriteAllText(sScriptFile, PowerShellScriptXML.Value, False, Text.Encoding.ASCII)
Dim proc = System.Diagnostics.Process.Start("PowerShell", sScriptFile)
proc.WaitForExit()
Dim ss = My.Computer.FileSystem.ReadAllText(sOutputFile)
MsgBox("Proc Done " + ss)
End Sub
End Module
End of code
See also
How to create the general purpose "T1.c1" server: Blogs get 300 hits per hour: Visual FoxPro can count.
Comments
Anonymous
October 23, 2007
One of the things I most dearly missed from FoxPro when I moved to VB.NET was the ability to easily dumpAnonymous
June 01, 2009
PingBack from http://uniformstores.info/story.php?id=19149Anonymous
October 13, 2009
The comment has been removed