Skip to content

Running PowerShell script with F5 changes current directory #1330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
SlyEcho opened this issue May 21, 2018 · 15 comments · Fixed by #1397
Closed

Running PowerShell script with F5 changes current directory #1330

SlyEcho opened this issue May 21, 2018 · 15 comments · Fixed by #1397
Labels

Comments

@SlyEcho
Copy link

SlyEcho commented May 21, 2018

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.

@rkeithhill
Copy link
Contributor

rkeithhill commented May 22, 2018

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.

@joeyaiello
Copy link

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.

@joeyaiello
Copy link

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

@SlyEcho
Copy link
Author

SlyEcho commented May 23, 2018

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.

@TylerLeonhardt
Copy link
Member

TylerLeonhardt commented May 24, 2018

@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.

@rkeithhill
Copy link
Contributor

rkeithhill commented May 24, 2018

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. :-(

@TylerLeonhardt
Copy link
Member

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

@bgraeb
Copy link

bgraeb commented May 25, 2018

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.

@Glober777
Copy link

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?

@TylerLeonhardt
Copy link
Member

@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.

@bgraeb
Copy link

bgraeb commented May 25, 2018

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.

@dragonwolf83
Copy link

dragonwolf83 commented May 26, 2018

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.

@bgraeb
Copy link

bgraeb commented May 26, 2018

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

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

@dragonwolf83
Copy link

@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.

rkeithhill added a commit that referenced this issue Jul 2, 2018
Fix #1330

This PR depends on a corresponding PR to PSES to have it handle
null/empty string differently in the non-temp console case.

For the generateLaunchConfig case, we now pass "" as cwd to PSES.
That tells PSES to not change the directory *if* we aren't running
in a temp console.  If we are in a temp console, then use old logic to
set working dir.

Update "PowerShell Interactive Session" debug config to tell PSES
to not change the working dir.

Remove "program" field from launch config. This has been marked
deprecated for over a year now.

Change refs in ${workspaceRoot} to ${workpaceFolder} to work
better in a multi-workspace environment.

Remove unused imports/field in DebugSession.ts.
rkeithhill added a commit to rkeithhill/PowerShellEditorServices that referenced this issue Jul 2, 2018
Fix for PowerShell/vscode-powershell#1330

Removes deprecated "Program" field from LaunchRequest class.
Simplifies working dir logic in HandleLaunchRequest.  Basically if the
launch request happens in the regular integrated console, a null/empty
cwd means "do not change the working dir".  If the request is using the
temp integrated console, there is no "existing" workng dir, so we use
the original logic to set the working dir.
rkeithhill added a commit to PowerShell/PowerShellEditorServices that referenced this issue Jul 2, 2018
Fix for PowerShell/vscode-powershell#1330

Removes deprecated "Program" field from LaunchRequest class.
Simplifies working dir logic in HandleLaunchRequest.  Basically if the
launch request happens in the regular integrated console, a null/empty
cwd means "do not change the working dir".  If the request is using the
temp integrated console, there is no "existing" workng dir, so we use
the original logic to set the working dir.
rkeithhill added a commit to PowerShell/PowerShellEditorServices that referenced this issue Jul 4, 2018
…#694)

* Change debug launch handler to treat null/empty cwd to not change dir

Fix for PowerShell/vscode-powershell#1330

Removes deprecated "Program" field from LaunchRequest class.
Simplifies working dir logic in HandleLaunchRequest.  Basically if the
launch request happens in the regular integrated console, a null/empty
cwd means "do not change the working dir".  If the request is using the
temp integrated console, there is no "existing" workng dir, so we use
the original logic to set the working dir.

* Address PR feedback, reorg to not execute working dir code unless used

* Get rid of unnecessary pragma warning disable
rkeithhill added a commit that referenced this issue Jul 4, 2018
Fix #1330

This PR depends on a corresponding PR to PSES to have it handle
null/empty string differently in the non-temp console case.

For the generateLaunchConfig case, we now pass "" as cwd to PSES.
That tells PSES to not change the directory *if* we aren't running
in a temp console.  If we are in a temp console, then use old logic to
set working dir.

Update "PowerShell Interactive Session" debug config to tell PSES
to not change the working dir.

Remove "program" field from launch config. This has been marked
deprecated for over a year now.

Change refs in ${workspaceRoot} to ${workpaceFolder} to work
better in a multi-workspace environment.

Remove unused imports/field in DebugSession.ts.
@rkeithhill
Copy link
Contributor

rkeithhill commented Jul 4, 2018

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 "".

rjmholt pushed a commit that referenced this issue Jul 11, 2018
Fix #1330

This PR depends on a corresponding PR to PSES to have it handle
null/empty string differently in the non-temp console case.

For the generateLaunchConfig case, we now pass "" as cwd to PSES.
That tells PSES to not change the directory *if* we aren't running
in a temp console.  If we are in a temp console, then use old logic to
set working dir.

Update "PowerShell Interactive Session" debug config to tell PSES
to not change the working dir.

Remove "program" field from launch config. This has been marked
deprecated for over a year now.

Change refs in ${workspaceRoot} to ${workpaceFolder} to work
better in a multi-workspace environment.

Remove unused imports/field in DebugSession.ts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants