Reputation: 2742
I'm using the System.Management.Automation API to call PowerShell scripts a C# WPF app. In the following example, how would you change the start directory ($PWD) so it executes foo.ps1 from C:\scripts\ instead of the location of the .exe it was called from?
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (Pipeline pipeline = runspace.CreatePipeline())
{
pipeline.Commands.Add(@"C:\scripts\foo.ps1");
pipeline.Invoke();
}
runspace.Close();
}
Upvotes: 19
Views: 11496
Reputation: 1198
Instead of letting the application handle it, you can include this at the start of your script,
Set-Location $PSScriptRoot
It would execute the rest of the script in its installation directory.
But beware, the PowerShell 'current location' is NOT the same as the working directory of your application, they're just initialized the same when you launch powershell.
Set-Location may play tricks on you if you launch executables that depend on the current directory, or if your script contains framework API calls like this example:
PS C:\Users\luc> Set-Location C:\
PS C:\> [System.IO.Directory]::GetCurrentDirectory()
C:\Users\luc
That being said, I would often prefer Mike Bailey's answer. I just wanted to give a solution that has its merits if the script isn't always installed in the same directory (different path on a development machine than in production, as is usually the case).
Upvotes: 0
Reputation: 12817
You don't need to change the System.Environment.CurrentDirectory
to change the working path for your PowerShell scripts. It can be quite dangerous to do this because this may have unintentional side effects if you're running other code that is sensitive to your current directory.
Since you're providing a Runspace
, all you need to do is set the Path
properties on the SessionStateProxy
:
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
runspace.SessionStateProxy.Path.SetLocation(directory);
using (Pipeline pipeline = runspace.CreatePipeline())
{
pipeline.Commands.Add(@"C:\scripts\foo.ps1");
pipeline.Invoke();
}
runspace.Close();
}
Upvotes: 17
Reputation: 15824
Setting System.Environment.CurrentDirectory
ahead of time will do what you want.
Rather than adding Set-Location
to your scrip, you should set System.Environment.CurrentDirectory
any time before opening the Runspace. It will inherit whatever the CurrentDirectory is when it's opened:
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
System.Environment.CurrentDirectory = "C:\\scripts";
runspace.Open();
using (Pipeline pipeline = runspace.CreatePipeline())
{
pipeline.Commands.Add(@".\foo.ps1");
pipeline.Invoke();
}
runspace.Close();
}
And remember, Set-Location
doesn't set the .net framework's CurrentDirectory
so if you're calling .Net methods which work on the "current" location, you need to set it yourself.
Upvotes: 8
Reputation: 16196
You can set the working directory in powershell with the following command
set-location c:\mydirectory
You can also try your PowerShell startup script ($profile). C:....\MyDocs\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 But only if this directory is fixed and does not change
Upvotes: 1
Reputation: 52430
Anything wrong with doing:
pipeline.Commands.AddScript(@"set-location c:\scripts;.\foo.ps1")
?
-Oisin
Upvotes: 4