我正在使用System.Management.Automation API将PowerShell脚本称为C#WPF应用程序。在下面的示例中,您将如何更改起始目录($ PWD),以便它从C:\ scripts \执行foo.ps1而不是从它调用的.exe的位置?
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
using (Pipeline pipeline = runspace.CreatePipeline())
{
pipeline.Commands.Add(@"C:\scripts\foo.ps1");
pipeline.Invoke();
}
runspace.Close();
}
答案 0 :(得分:10)
您无需更改System.Environment.CurrentDirectory
即可更改PowerShell脚本的工作路径。执行此操作可能非常危险,因为如果您运行的是对当前目录敏感的其他代码,则可能会产生无意的副作用。
由于您提供的是Runspace
,因此您需要做的就是在Path
上设置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();
}
答案 1 :(得分:7)
提前设置System.Environment.CurrentDirectory
会做你想要的。
您应该在开始运行空间之前随时设置Set-Location
,而不是将System.Environment.CurrentDirectory
添加到您的脚本中。它将继承CurrentDirectory打开时的内容:
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();
}
请记住,Set-Location
没有设置.net框架的CurrentDirectory
,所以如果你调用的是在“当前”位置工作的.Net方法,你需要自己设置它。 / p>
答案 2 :(得分:3)
做错了什么:
pipeline.Commands.AddScript(@"set-location c:\scripts;.\foo.ps1")
-Oisin
答案 3 :(得分:1)
您可以使用以下命令在powershell中设置工作目录
set-location c:\mydirectory
您还可以尝试使用PowerShell启动脚本($ profile)。 C:.... \ MyDocs \ WindowsPowerShell \ Microsoft.PowerShell_profile.ps1 但仅当此目录已修复且未更改
时答案 4 :(得分:0)
您可以在脚本的开头添加这个内容,而不是让应用程序来处理它,
Set-Location $PSScriptRoot
它将在其安装目录中执行脚本的其余部分。
但是请注意,PowerShell的“当前位置”与应用程序的工作目录不同,启动Powershell时它们只是被初始化。
如果启动依赖于当前目录的可执行文件,或者您的脚本包含框架API调用(如以下示例),则Set-Location可能会给您带来麻烦:
PS C:\Users\luc> Set-Location C:\
PS C:\> [System.IO.Directory]::GetCurrentDirectory()
C:\Users\luc
话虽这么说,我通常会更喜欢Mike Bailey的回答。我只是想给出一个有其优点的解决方案,如果脚本并非总是安装在同一目录中(通常情况下,开发机器上的路径与生产机器上的路径不同)。