proxb / PoshRSJob

Provides an alternative to PSjobs with greater performance and less overhead to run commands in the background, freeing up the console and allowing throttling on the jobs.
MIT License
541 stars 87 forks source link

Named parameters for imported functions don't work in ISE or VSCode PS plugin's Integrated Console #196

Open ALuckyGuy opened 5 years ago

ALuckyGuy commented 5 years ago

Named parameters passed to imported functions don't work within the PowerShell ISE or VSCode's Powershell plugin's Integrated Console. Works fine otherwise, including within VSCode's PS console (unrelated to the plugin). Not sure if this is a PoshRSJob bug or not, but if not there ought to at least be some kind of warning or error if running within these well-known consoles.

I'm running Windows 10, PS version 5.1.14393.2430, VSCode v1.27.2, Powershell plugin v 1.9.0

Below is an example that shows the problem. Notice that if a parameter has the same name as a local variable of a caller, things appear to be fine because the references take on the value from the caller's local scope. That made figuring this out really confusing.

Also, notice calling a function declared within the scriptblock with named parameters works fine. Outputing the $args value within the called function shows the difference in how the function gets called

function show-parm( $s, $sameName ) {
   # because this function has a parameter with the same name as a local variable for the caller,
   # that parameter seems to be set correctly. It's not though.
   [pscustomobject]@{ str1 = $s 
                      str2 = $sameName
                      argCount = $args.count
                      args = $args } 
}

# the imported show-parm function won't get parameter values passed in the VSCode integrated console
[pscustomobject]@{ str      = 'a string'
                   sameName = 'misleading' }  | Start-RSJob `
                 -FunctionsToImport 'show-parm'  -script { 
                         $str      = $_.str
                         $sameName = $_.sameName
                         "Before call: [$str] [$sameName]"
                         show-parm -s $str -sameName $sameName
                   } | wait-rsjob | receive-rsjob

# the locally declared show-parm function receives parameters corrected
[pscustomobject]@{ str      = 'a string'
                   sameName = 'misleading' }  | Start-RSJob  -script { 
                        function show-parm( $s, $sameName ) {
                           [pscustomobject]@{ str1 = $s 
                                              str2 = $sameName
                                              argCount = $args.count
                                              args = $args } 
                        }
                        $str      = $_.str
                        $sameName = $_.sameName
                        "Before call: [$str] [$sameName]"
                        show-parm -s $str -sameName $sameName
                     } | wait-rsjob | receive-rsjob

get-rsjob | remove-rsjob
MVKozlov commented 5 years ago

As far as I see there is some error in function definition under ISE Place $DebugPreference = 'Continue' before you script and you see:

clean PS

ОТЛАДКА: [BEGIN]
ОТЛАДКА: Definition: param($s, $sameName)

   # because this function has a parameter with the same name as a local variable for the caller,
   # that parameter seems to be set correctly. It's not though.
   [pscustomobject]@{ str1 = $s
                      str2 = $sameName
                      argCount = $args.count
                      args = $args }
ОТЛАДКА: ListCount: 0

ISE

ОТЛАДКА: [BEGIN]
ОТЛАДКА: Definition: 
   # because this function has a parameter with the same name as a local variable for the caller,
   # that parameter seems to be set correctly. It's not though.
   [pscustomobject]@{ str1 = $s 
                      str2 = $sameName
                      argCount = $args.count
                      args = $args } 

ОТЛАДКА: ListCount: 0

take a note that under ISE there is no param() block ! But I Can't reproduce it with plain test like

function test ($param1, $param2, $param3) { $param1,$param2,$param3 }
get-content function:\test
param($param1, $param2, $param3)
 $param1,$param2,$param3

seems there is a some error in RegisterScriptScopeFunction