2013-09-10 1 views
7

У меня возникла странная проблема, когда у меня возникает другое поведение при установке «Set-PSDebug -Trace 2».Powershell «Set-PSDebug -Trace 2» вызывает неожиданные результаты

Я проследил его до переключателя заявление не исполняющего должным образом и был в состоянии воспроизвести его на Powershell V3, но не на Powershell V2 или Powershell V1 (работает как ожидалось)

Возьмем следующую простую функцию:

function DoTest { 
$result = "Switch Case Not Executed" 
$VendorName = "Microsoft" 
switch ($VendorName) 
{ 
    "Microsoft" { $result = "Switch Case Executed" } 
} 
Write-host "Switch: $($VendorName) -> $result" 

}

Теперь выполните следующее:

#Works as expected 
Set-PSDebug -Off; DoTest; 

#Doesn't work as expected 
Set-PSDebug -Trace 2; DoTest; 

Результаты на шикарном V3 с PSDebug Трассировка

DEBUG: 3+ Set-PSDebug -Trace 2; >>>> DoTest; 
DEBUG: 1+ function DoTest >>>> { 
DEBUG:  ! CALL function 'DoTest' 
DEBUG: 2+  >>>> $result = "Switch Case Not Executed" 
DEBUG:  ! SET $result = 'Switch Case Not Executed'. 
DEBUG: 3+  >>>> $VendorName = "Microsoft" 
DEBUG:  ! SET $VendorName = 'Microsoft'. 
DEBUG:  ! SET $switch = 'Microsoft'. 
DEBUG: 4+  switch (>>>> $VendorName) 
DEBUG:  ! SET $switch = ''. 
DEBUG: 9+  >>>> Write-host "Switch: $($VendorName) -> $result" 
DEBUG: 9+  Write-host "Switch: $(>>>> $VendorName) -> $result" 
Switch: Microsoft -> Switch Case Not Executed 
DEBUG: 11+ >>>> } 

В шикарном 3-й версии, даже трассировка отладки указывает, что значение установлено, но, кажется, пропустить заявление переключатель полностью. Я даже попробовал Set-StrictMode, и все работает нормально. Это только когда я включаю трассировку PSDebug. Предполагается ли это поведение?

ответ

2

После исчерпывающего расследования это кажется ошибкой в ​​Powershell. Переменная $switch получает clobbered в режиме отладки и заканчивает тем, что является своего рода перечислителем массива, на пустом массиве или чем-то глупо. Я рекомендую подав вопрос о http://connect.microsoft.com

Обход 1:

# Pro: No scoping differences between if statement blocks and function 
# Con: big piles of If ... else if ... else if ... can get really annoying to code and maintain 
# Con: Statements are limited to single execution, pipeline is lifted to function level instead of statement level 
... same code as before but using an if instead of switch ... 
if($VendorName = 'Microsoft') { $result = "Switch Case Executed" } 
else { $result = "FAIL!" } 

Обход 2:

# Pro: Each script block is self-contained and has private scope 
# Pro: "cases" can be added without modifying DoIt function, and even passed into the function 
# Pro: "cases" can be used in a pipeline 
# Con: Indirect script blocks can be difficult to understand at first 
function DoTest { 
    $result = "Switch Case Not Executed" 
    $VendorName = "Microsoft" 

    $SwitchHack = @{ 
     Microsoft = { "Microsoft Case Executed" } 
     Default = { "Default Case Executed" } 
    } 

    if($SwitchHack.Keys -contains $VendorName) { 
     $result = $SwitchHack."$VendorName".InvokeReturnAsIs() 
    } else { 
     $result = $SwitchHack.Default.InvokeReturnAsIs() 
    } 

    'Switch: {0} -> {1}' -f $VendorName, $result | Write-Host 
} 

Set-PSDebug -Trace 2 
DoTest 

И потому, что мне было скучно, я написал Обход 3, который только 2 с коммутатором переехал a

function Switch-Object { 
    param(
     [Parameter(Mandatory=$true)] 
      [String]$In, 
     [Parameter(Mandatory=$true)] 
      [hashtable]$Actions 
    ) 

    try { 
     $Actions."$In".InvokeReturnAsIs() 
    } 
    catch { 
     throw "Unknown Action Label" 
    } 
} 

function DoTest { 
    $result = "Switch Case Not Executed" 
    $VendorName = "Microsoft" 

    $VendorActions = @{ 
     Microsoft = { "Microsoft Case Executed" } 
    } 

    $result = Switch-Object -On:$VendorName -Actions:$VendorActions 
    'Switch: {0} -> {1}' -f $VendorName, $result | Write-Host 
} 

Set-PSDebug -Trace 2 
DoTest 
+1

Thanks @Eris! Я открыл ошибку с помощью [Microsoft Connect] (https://connect.microsoft.com/PowerShell/feedback/details/800248/set-psdebug-trace-2-on-powershell-v3-does-not-execute -switch-statements-correct-switch-is-null) –

+0

У нас была аналогичная проблема с использованием 'Set-PSDebug -Trace 1' и foreach. Если мы делаем 'foreach (var $ item в $ something)', то итерации не происходит. Работает отлично с '$ something ' ForEach-Object' ... хотя. Мы использовали трассировку для оценки охвата кода на автоматизированных тестах - теперь это сильно нарушено при использовании PowerShell 3 ... – MrKWatkins