I am writing a simple script on Windows PowerShell in order to evaluate performance of executable files.
The important hypothesisi is the following: I have an executable file, it can be an application written in any possible language (.net and not, Viual-Prolog, C++, C, everything that can be compiled as an .exe
file). I want to profile it getting execution times.
I did this:
Function Time-It {
Param ([string]$ProgramPath, [string]$Arguments)
$Watch = New-Object System.Diagnostics.Stopwatch
$NsecPerTick = (1000 * 1000 * 1000) / [System.Diagnostics.Stopwatch]::Frequency
Write-Output "Stopwatch created! NSecPerTick = $NsecPerTick"
$Watch.Start() # Starts the timer
[System.Diagnostics.Process]::Start($ProgramPath, $Arguments)
$Watch.Stop() # Stops the timer
# Collectiong timings
$Ticks = $Watch.ElapsedTicks
$NSecs = $Watch.ElapsedTicks * $NsecPerTick
Write-Output "Program executed: time is: $Nsecs ns ($Ticks ticks)"
}
This function uses stopwatch.
Well, the functoin accepts a program path, the stopwatch is started, the program run and the stopwatch then stopped. Problem: the System.Diagnostics.Process.Start
is asynchronous and the next instruction (watch stopped) is not executed when the application finishes. A new process is created...
I need to stop the timer once the program ends.
I thought about the Process
class, thicking it held some info regarding the execution times... not lucky...
How to solve this?
The Windows PowerShell 2.0 Engine is intended to be used only when an existing script or host program cannot run because it is incompatible with Windows PowerShell 5.1. Examples of this include older versions of Exchange or SQL Server modules. Such cases are expected to be rare.
You can run .exe files in PowerShell using three different methods: Typing “. \” followed by the name of the file. Using Invoke-Expression.
PowerShell 7.0 marks a move a to . NET Core 3.1, enabling significantly more backwards compatibility with existing Windows PowerShell modules. This includes many modules on Windows that require GUI functionality like Out-GridView and Show-Command , as well as many role management modules that ship as part of Windows.
PowerShell can be used as an open-source shell or as a scripting language. PowerShell is used as a shell to control the computer with commands from a command-line interface related to the operating system.
You can use Process.WaitForExit()
$proc = new-object "System.Diagnostics.Process"
$proc.StartInfo.FileName = "notepad.exe"
$proc.StartInfo.UseShellExecute = $false
$proc.Start()
$proc.WaitForExit()
Here's kprobst's answer, combined with the Measure-Command CmdLet, for a complete solution:
$proc = new-object "System.Diagnostics.Process"
$proc.StartInfo.FileName = "notepad.exe"
$proc.StartInfo.UseShellExecute = $false
$timeSpan = (MeasureCommand {
$proc.Start()
$proc.WaitForExit()
}
);
"Program executed: Time is {0} seconds" -f $timeSpan.TotalSeconds;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With