Vscode-powershell: Running PowerShell script with F5 changes current directory

Created on 21 May 2018  路  15Comments  路  Source: PowerShell/vscode-powershell

System Details

  • Operating system name and version: Windows 10
  • VS Code version: 1.23.1
  • PowerShell extension version: 1.7.0
  • Output from $PSVersionTable:
Name                           Value
----                           -----
PSVersion                      5.1.17134.48
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17134.48
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Issue Description

Running PowerShell script with F5 changes current directory to the same folder that the script is located in.

Most of my scripts are written in a way that don't reference a specific fixed path but work with files in $PWD. If I need any files from the script's folder I can use $PSScriptRoot.

This behavior is unexpected and different from the ISE, and is preventing me from moving over to VS Code.

Area-Debugging Issue-Discussion

Most helpful comment

If anybody wants to grab a daily build of the extension and verify this fix, it would be greatly appreciated. In the "no debug-config" scenario, the working dir will not be changed for execution in the PS integrated console. If you're using the temp console, then we will set the working dir.

If you have a debug config (.vscode\launch.json file) and don't want to have the PSIC's working dir changed, either remove the "cwd": setting or set it to "".

All 15 comments

I think I see where the issue lies. The only workaround for now is to specify the cwd field in the launch config which is in the launch.json file. Note: you can copy an existing config like "Launch Current File" - give it a new name e.g.:

        {
            "type": "PowerShell",
            "request": "launch",
            "name": "PowerShell Launch My Script",
            "script": "${workspaceFolder}/<path-to-script>",
            "args": [],
            "cwd": "<path-to-startup-working-dir>"
        },

I believe we need to make a change in the PSES handleLaunchRequest method to accept an empty string to mean "don't mess with the current working dir". I think this cropped up because in the early, early days of this extension there was no PSIC that hung around. We always fired up a new debug adapter server every time you started a debug session. We wanted to make sure we set cwd to a reasonable place.

Theoretically, this is a breaking change, but I think it would only affect people using relative directories in their scripts without using $PSScriptRoot.

We could add two side-by-side launch configuration (there's a cwd in launch.json), but unless people push back and come up with more scenarios than what I said above, I think we should just make it the default to fall in line with ISE.

Whoa, @rkeithhill beat me.... :'(

I don't have a launch.json set up. I don't even have a folder open I only have a Powershell file. The usual workflow with Powershell has been to either open the script in ISE, cd to the folder I want to run it in and then press F5; or open a Powershell window then cd into the folder and run the script using its path (or name if I have it in a module).

I only brought this up because ISE seems a little broken after the last Windows Update and I've read that MS is not planning on updating it and they are encouraging people to migrate to Code + this extension. Having to set up a folder and separate launch configs for each script seems like overkill to me.

@SlyEcho I agree. I think the default behavior should mirror the ISE - debug should be launched in the current directory rather than the directory of the script file.

I'll give this a week or two to gather feedback from the community on this breaking change.

There may be some complication here if the user has the createTemporaryIntegratedConsole setting set to true. In that case, I suppose we could copy the dir from the current PSIC except that they may have PSIC set to not automatically start. Anyway, it gets a little complicated when you take into consideration all the settings. :-(

Good point @rkeithhill, maybe we should scope this to just the default behavior if there is no launch config?

From the usage point of view, I'd rather have the pwd set to the workspace root instead of the script files root, as (my) projects reference everything else starting from there (often by .../-stuff). However, I'd like to see the pwd not changed, instead of changing it to $PSScriptroot.

My preference is the same as @bgraeb has expressed. On the other hand, since the default behavior is different in ISE and there's some fair reasoning behind it, could this be something that's controlled by some user setting?

@bgraeb + @Glober777 That makes total sense. Just out of curiosity, can you try the following launch config:

{
      "type": "PowerShell",
      "request": "launch",
      "name": "PowerShell Launch Current File From Workspace Folder",
      "script": "${file}",
      "args": [],
      "cwd": "${workspaceFolder}"
},

and see if that does what you're expecting.

I'd lean more in favor of changing the default behavior (as in, when no launch config is given) to what the ISE does since that is what we're trying to get parity with to convince those that still use it to switch.

For someone who wants it set to the workspace folder, a launch config could be added with that snippet. It makes a little more sense to have the person who wants it set to the workspace folder add the launch config vs someone who just wants to jump around and debug anywhere.

That's my opinion.

I'd say, the guy that only want to jump around and debug, would not except things to explode, just because a script is somewhere inside the repo structure. When you just F5 a file, you'll end up somewhere and have to think about, where you are, how you come back (is there a default variable for this, that I'm not aware of?) to where you left of.

Beneath that: I'm to stupid to memorize the syntax and variable notation to construct the config you gave, on my own (google ftw). Might be an issue for me only, but I'd say that the default way to run things (ISE default'ish) would be: Hit F5

But, don't want to argue about, just expand my thoughts on that.

Using the cwd path like ISE is the better option for a default. To be more accurate, it needs to align with the defaults on how scripts execute in a normal PowerShell Terminal. This ensures that a script you write will run exactly the way you would expect it to run when called from powershell.exe. Any other default will cause you hours of pain trying to figure out why it doesn't work right when run from production.

For example, I create a script named $env:USERPROFILE\Documents\GetFiles.ps1 and all it does is run Get-ChildItem. When I run powershell.exe and go to my Windows folder and call GetFiles, I will get a list of files from my Windows folder, not from My Documents folder. If I want it from My Documents folder, I use $PSScriptRoot

@bgraeb as I show above, I would expect things to explode if you jump around and the debugging experience of using cwd path would tell you why. To make a script resilient, it needs reliable path variables set. In most cases, that is $PSScriptRoot. You can't use WorkSpace Root because outside of VS Code, that concept won't exist.

@dragonwolf83 Yeah, thats true. Maybe I went the wrong path there, with my message.

However, changing $PWD is still another point, right?

@bgraeb changing $PWD would break running scripts in PowerShell and change the meaning of the variable.

From the documentation:

$PWD
Contains a path object that represents the full path of the current directory.

I think a separate entry in launch.json is the best route to always debug with WorkSpace Root. VSCode always remembers the last debug config you used.

As for difficultly in customizing the launch.json, it is actually quite easy. You won't be creating it from scratch and it has intellisense to show you the options to choose.

  1. Go to Debug menu and choose Add Configurations...
  2. Choose from one of the existing PowerShell configurations
  3. Change the name setting to what you want
  4. Edit any other setting
  5. Add a setting by adding a newline and add "", intellisense will appear.

If anybody wants to grab a daily build of the extension and verify this fix, it would be greatly appreciated. In the "no debug-config" scenario, the working dir will not be changed for execution in the PS integrated console. If you're using the temp console, then we will set the working dir.

If you have a debug config (.vscode\launch.json file) and don't want to have the PSIC's working dir changed, either remove the "cwd": setting or set it to "".

Was this page helpful?
0 / 5 - 0 ratings