MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4Describe "Start-Process" -Tag "Feature","RequireAdminOnWindows" {5 6 BeforeAll {7 $isNanoServer = [System.Management.Automation.Platform]::IsNanoServer8 $isIot = [System.Management.Automation.Platform]::IsIoT9 $isFullWin = $IsWindows -and !$isNanoServer -and !$isIot10 $extraArgs = @{}11 if ($isFullWin) {12 $extraArgs.WindowStyle = "Hidden"13 }14 15 $pingCommand = (Get-Command -CommandType Application ping)[0].Definition16 $pingDirectory = Split-Path $pingCommand -Parent17 $tempFile = Join-Path -Path $TestDrive -ChildPath PSTest18 $tempDirectory = Join-Path -Path $TestDrive -ChildPath 'PSPath[]'19 New-Item $tempDirectory -ItemType Directory -Force20 $assetsFile = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath assets) -ChildPath SortTest.txt21 if ($IsWindows) {22 $pingParam = "-n 2 localhost"23 }24 elseif ($IsLinux -Or $IsMacOS) {25 $pingParam = "-c 2 localhost"26 }27 }28 29 # Note that ProcessName may still be `powershell` due to dotnet/corefx#537830 # This has been fixed on Linux, but not on macOS31 32 It "Should process arguments without error" {33 $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs34 35 $process.Length | Should -Be 136 $process.Id | Should -BeGreaterThan 137 # $process.ProcessName | Should -Be "ping"38 }39 40 It "Should work correctly when used with full path name" {41 $process = Start-Process $pingCommand -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs42 43 $process.Length | Should -Be 144 $process.Id | Should -BeGreaterThan 145 # $process.ProcessName | Should -Be "ping"46 }47 48 It "Should invoke correct path when used with FilePath argument" {49 $process = Start-Process -FilePath $pingCommand -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs50 51 $process.Length | Should -Be 152 $process.Id | Should -BeGreaterThan 153 # $process.ProcessName | Should -Be "ping"54 }55 56 It "Should invoke correct path when used with Path alias argument" {57 $process = Start-Process -Path $pingCommand -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs58 59 $process.Length | Should -Be 160 $process.Id | Should -BeGreaterThan 161 }62 63 It "Should wait for command completion if used with Wait argument" {64 $process = Start-Process ping -ArgumentList $pingParam -Wait -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs65 }66 67 It "Should work correctly with WorkingDirectory argument" {68 $process = Start-Process ping -WorkingDirectory $pingDirectory -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs69 70 $process.Length | Should -Be 171 $process.Id | Should -BeGreaterThan 172 # $process.ProcessName | Should -Be "ping"73 }74 75 It "Should work correctly within an unspecified WorkingDirectory with wildcard-type characters" {76 Push-Location -LiteralPath $tempDirectory77 $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs78 $process.Length | Should -Be 179 $process.Id | Should -BeGreaterThan 180 # $process.ProcessName | Should -Be "ping"81 Pop-Location82 }83 84 It "Should handle stderr redirection without error" {85 $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardError $tempFile -RedirectStandardOutput "$TESTDRIVE/output" @extraArgs86 87 $process.Length | Should -Be 188 $process.Id | Should -BeGreaterThan 189 # $process.ProcessName | Should -Be "ping"90 }91 92 It "Should handle stdout redirection without error" {93 $process = Start-Process ping -ArgumentList $pingParam -Wait -RedirectStandardOutput $tempFile @extraArgs94 $dirEntry = Get-ChildItem $tempFile95 $dirEntry.Length | Should -BeGreaterThan 096 }97 98 It "Should handle stdin redirection without error" {99 $process = Start-Process sort -Wait -RedirectStandardOutput $tempFile -RedirectStandardInput $assetsFile @extraArgs100 $dirEntry = Get-ChildItem $tempFile101 $dirEntry.Length | Should -BeGreaterThan 0102 }103 104 ## -Verb is supported in PowerShell on Windows full desktop.105 It "Should give an error when -Verb parameter is used" -Skip:$isFullWin {106 { Start-Process -Verb runas -FilePath $pingCommand } | Should -Throw -ErrorId "NotSupportedException,Microsoft.PowerShell.Commands.StartProcessCommand"107 }108 109 ## -WindowStyle is supported in PowerShell on Windows full desktop.110 It "Should give an error when -WindowStyle parameter is used" -Skip:$isFullWin {111 { Start-Process -FilePath $pingCommand -WindowStyle Normal } | Should -Throw -ErrorId "NotSupportedException,Microsoft.PowerShell.Commands.StartProcessCommand"112 }113 114 It "Should give an error when both -NoNewWindow and -WindowStyle are specified" -Skip:(!$isFullWin) {115 { Start-Process -FilePath $pingCommand -NoNewWindow -WindowStyle Normal -ErrorAction Stop } | Should -Throw -ErrorId "InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand"116 }117 118 It "ExitCode returns with -NoNewWindow, -PassThru and -Wait" {119 $process = Start-Process -FilePath $pingCommand -ArgumentList $pingParam -NoNewWindow -PassThru -Wait -ErrorAction Stop120 $process.ExitCode | Should -Be 0121 }122 123 It "Should start cmd.exe with Verb 'open' and WindowStyle 'Minimized'" -Skip:(!$isFullWin) {124 $fileToWrite = Join-Path $TestDrive "VerbTest.txt"125 $process = Start-Process cmd.exe -ArgumentList "/c echo abc > $fileToWrite" -Verb open -WindowStyle Minimized -PassThru126 $process.Name | Should -Be "cmd"127 $process.WaitForExit()128 Test-Path $fileToWrite | Should -BeTrue129 }130 131 It "Should start notepad.exe with ShellExecute" -Skip:(!$isFullWin) {132 $process = Start-Process notepad.exe -PassThru -WindowStyle Normal133 $process.Name | Should -Be "notepad"134 $process | Stop-Process135 }136 137 It "Should be able to use the -WhatIf switch without performing the actual action" {138 $pingOutput = Join-Path $TestDrive "pingOutput.txt"139 { Start-Process -Wait $pingCommand -ArgumentList $pingParam -RedirectStandardOutput $pingOutput -WhatIf -ErrorAction Stop @extraArgs} | Should -Not -Throw140 $pingOutput | Should -Not -Exist141 }142 143 It "Should return null when using -WhatIf switch with -PassThru" {144 Start-Process $pingCommand -ArgumentList $pingParam -PassThru -WhatIf | Should -BeNullOrEmpty145 }146 147 It 'Should run without errors when -ArgumentList is $null' {148 $process = Start-Process $pingCommand -ArgumentList $null -PassThru @extraArgs149 $process.Length | Should -Be 1150 $process.Id | Should -BeGreaterThan 1151 }152 153 It "Should run without errors when -ArgumentList is @()" {154 $process = Start-Process $pingCommand -ArgumentList @() -PassThru @extraArgs155 $process.Length | Should -Be 1156 $process.Id | Should -BeGreaterThan 1157 }158 159 It "Should run without errors when -ArgumentList is ''" {160 $process = Start-Process $pingCommand -ArgumentList '' -PassThru @extraArgs161 $process.Length | Should -Be 1162 $process.Id | Should -BeGreaterThan 1163 }164}165 166Describe "Start-Process tests requiring admin" -Tags "Feature","RequireAdminOnWindows" {167 168 BeforeEach {169 cmd /c assoc .foo=foofile170 cmd /c ftype foofile=cmd /c echo %1^> $testdrive\foo.txt171 Remove-Item $testdrive\foo.txt -Force -ErrorAction SilentlyContinue172 }173 174 AfterEach {175 cmd /c assoc .foo=176 cmd /c ftype foofile=177 }178 179 It "Should open the application that is associated a file" -Skip:(!$isFullWin) {180 $fooFile = Join-Path $TestDrive "FooTest.foo"181 New-Item $fooFile -ItemType File -Force182 Start-Process $fooFile183 184 Wait-FileToBePresent -File "$testdrive\foo.txt" -TimeoutInSeconds 10 -IntervalInMilliseconds 100 | Should -BeTrue185 Get-Content $testdrive\foo.txt | Should -BeExactly $fooFile186 }187}188 189Describe "Environment Tests" -Tags "Feature" {190 191 It "UseNewEnvironment parameter should reset environment variables for child process" {192 193 $PWSH = (Get-Process -Id $PID).MainModule.FileName194 $outputFile = Join-Path -Path $TestDrive -ChildPath output.txt195 196 $env:TestEnvVariable | Should -BeNullOrEmpty197 198 $env:TestEnvVariable = 1199 $userName = $env:USERNAME200 201 try {202 Start-Process $PWSH -ArgumentList '-NoProfile','-Command Write-Output \"$($env:TestEnvVariable);$($env:USERNAME)\"' -RedirectStandardOutput $outputFile -Wait203 Get-Content -LiteralPath $outputFile | Should -BeExactly "1;$userName"204 205 # Check that:206 # 1. Environment variables is resetted (TestEnvVariable is removed)207 # 2. Environment variables comes from current user profile208 Start-Process $PWSH -ArgumentList '-NoProfile','-Command Write-Output \"$($env:TestEnvVariable);$($env:USERNAME)\"' -RedirectStandardOutput $outputFile -Wait -UseNewEnvironment209 Get-Content -LiteralPath $outputFile | Should -BeExactly ";$userName"210 } finally {211 $env:TestEnvVariable = $null212 }213 }214 215 It '-Environment adds or replaces environment variables to child process' {216 $outputfile = Join-Path -Path $TestDrive -ChildPath output.txt217 Start-Process pwsh -ArgumentList '-NoProfile','-Nologo','-OutputFormat xml','-Command get-childitem env:' -Wait -Environment @{ a = 1; B = 'hello'; TERM = 'dumb'; PATH = 'mine' } -RedirectStandardOutput $outputfile218 $out = Import-Clixml $outputfile219 ($out | Where-Object { $_.Name -eq 'a' }).Value | Should -Be 1220 ($out | Where-Object { $_.Name -eq 'B' }).Value | Should -BeExactly 'hello'221 ($out | Where-Object { $_.Name -eq 'TERM' }).Value | Should -BeExactly 'dumb'222 $pathSeparator = [System.IO.Path]::PathSeparator223 if ($IsWindows) {224 ($out | Where-Object { $_.Name -eq 'PATH' }).Value | Should -BeLike "*${pathSeparator}mine${pathSeparator}*"225 } else {226 ($out | Where-Object { $_.Name -eq 'PATH' }).Value | Should -BeLike "*${pathSeparator}mine"227 }228 }229 230 It '-Environment can remove an environment variable from child process' {231 try {232 $env:existing = 1 # set a variable that we will remove233 $env:nonexisting = $null # validate that removing a non-existing variable is a no-op234 $outputfile = Join-Path -Path $TestDrive -ChildPath output.txt235 Start-Process pwsh -ArgumentList '-NoProfile','-Nologo','-OutputFormat xml','-Command get-childitem env:' -Wait -Environment @{ existing = $null; nonexisting = $null } -RedirectStandardOutput $outputfile236 $out = Import-Clixml $outputfile237 $out | Where-Object { $_.Name -eq 'existing' } | Should -BeNullOrEmpty238 $out | Where-Object { $_.Name -eq 'nonexisting' } | Should -BeNullOrEmpty239 } finally {240 $env:existing = $null241 }242 }243}244 245Describe "Bug fixes" -Tags "CI" {246 247 ## https://github.com/PowerShell/PowerShell/issues/24986248 It "Error redirection along with '-NoNewWindow' should work for Start-Process" -Skip:(!$IsWindows) {249 $errorFile = Join-Path -Path $TestDrive -ChildPath error.txt250 $out = pwsh -noprofile -c "Start-Process -Wait -NoNewWindow -RedirectStandardError $errorFile -FilePath cmd -ArgumentList '/C echo Hello'"251 252 ## 'Hello' should be sent to standard output; 'error.txt' file should be created but empty.253 $out | Should -BeExactly "Hello"254 Test-Path -Path $errorFile | Should -BeTrue255 (Get-Item $errorFile).Length | Should -Be 0256 }257}258 