Visual studio 2010 使用参数在后期生成中调用powershell脚本
我正试图让Powershell在后期构建中运行我的PS脚本,但不知何故,它的工作方式与预期的不同: 后期生成中的以下命令:Visual studio 2010 使用参数在后期生成中调用powershell脚本,visual-studio-2010,powershell,sharepoint-2010,build-process,Visual Studio 2010,Powershell,Sharepoint 2010,Build Process,我正试图让Powershell在后期构建中运行我的PS脚本,但不知何故,它的工作方式与预期的不同: 后期生成中的以下命令: C:\WINDOWS\system32\windowspowershell\1.0\powershell.exe -Command "& $(MSBuildProjectDirectory)\CreateSite.ps1 'auto'" (插入换行符以便更好地阅读) 该命令成功执行powershell脚本,但它无法在(生成输出)中运行命令: Rund生成后命令
C:\WINDOWS\system32\windowspowershell\1.0\powershell.exe
-Command "& $(MSBuildProjectDirectory)\CreateSite.ps1 'auto'"
(插入换行符以便更好地阅读)
该命令成功执行powershell脚本,但它无法在(生成输出)中运行命令:
Rund生成后命令:
Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2
At C:\path\CreateSite.ps1:4 char:
38
+ Add-PsSnapin <<<< Microsoft.SharePoint.PowerShell}
+ CategoryInfo : InvalidArgument: (Microsoft.SharePoint.PowerShell:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand
Add PSSnapin:尚未为Windows PowerShell版本2注册任何管理单元
在C:\path\CreateSite.ps1:4字符处:
38
+添加PsSnapin当您直接运行脚本时,您可能会在msbuild脚本中使用32位PowerShell和64位PowerShell,反之亦然。另请看。由于文件系统虚拟化,您无法从32位进程(即承载msbuild引擎的Visual Studio)指定64位版本PowerShell的路径。解决这一问题的一种黑客方法是创建一个64位启动器,以64位运行,并将启动64位版本的PowerShell。下面是一个简单的C#程序,可以实现这一点:
using System;
using System.Diagnostics;
class App
{
static int Main(string[] args)
{
Process process = Process.Start("PowerShell.exe", String.Join(" ", args));
process.WaitForExit();
return process.ExitCode;
}
}
请确保将其编译为64位,如下所示:
csc .\PowerShell64.cs /platform:x64
然后,从生成后事件执行此launcher exe,并向其传递要调用64位PowerShell的参数。此外,对于PowerShell 2.0,我建议使用文件
参数来执行脚本,例如:
c:\path\PowerShell64.exe -File "$(MSBuildProjectDirectory)\CreateSite.ps1" auto
也就是说,肯定有其他方法(实用程序)可以从64位进程启动EXE。输出重定向的一个稍好的变体:
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
namespace ConsoleApplication1
{
class App
{
static int Main(string[] args)
{
Console.WriteLine("sh64 args: " + string.Join(", ", args));
var start = new ProcessStartInfo
{
FileName = args.First(),
Arguments = string.Join(" ", args.Skip(1).ToArray()),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = false,
CreateNoWindow = true
};
using (var process = Process.Start(start))
{
while (!process.HasExited)
{
using (var reader = process.StandardOutput)
Drain(reader, false);
using (var reader = process.StandardError)
Drain(reader, true);
}
process.WaitForExit();
return process.ExitCode;
}
}
static void Drain(TextReader reader, bool error)
{
ColourizeError(error, () =>
{
var buf = new char[256];
int read;
while ((read = reader.Read(buf, 0, buf.Length)) != 0)
Console.Write(new string(buf, 0, read));
});
}
static void ColourizeError(bool error, Action a)
{
var prev = Console.ForegroundColor;
Console.ForegroundColor = error ? ConsoleColor.Red : ConsoleColor.White;
var mre = new ManualResetEventSlim(false);
try
{
a();
}
finally
{
Console.ForegroundColor = prev;
mre.Set(); // runs on GC thread on servers and is reentrant/interleaved concurrency in workstations!
}
mre.Wait();
}
}
}
调用sh64 powershell-File./buildscripts/deploy.ps1-Ex RemoteSigned
(此线程不是新线程,但我是从Google获得的,因此我认为共享我发现的解决方案会让其他人感兴趣)
我尝试将powershell.exe的路径更改为“%WINDIR%\SysNative\WindowsPowerShell\v1.0\powershell.exe”,效果非常好。从生成后事件调用64位版本,并成功添加SharePoint管理单元
这篇文章的作者:,“使用Windows PowerShell脚本在Visual Studio中自动执行任务”。使用以下内容添加cmd文件(例如run script.cmd):
@echo off
set pspath=%windir%\Sysnative\WindowsPowerShell\v1.0
if not exist %pspath%\powershell.exe set pspath=%windir%\System32\WindowsPowerShell\v1.0
%pspath%\powershell.exe -ExecutionPolicy RemoteSigned %*
@回音
设置pspath=%windir%\Sysnative\WindowsPowerShell\v1.0
如果不存在%pspath%\powershell.exe,请设置pspath=%windir%\System32\WindowsPowerShell\v1.0
%pspath%\powershell.exe-ExecutionPolicy RemoteSigned%*
并以以下方式从构建事件调用它:
$(SolutionDir)scripts\run-script.cmd $(SolutionDir)scripts\restore-default-file.ps1 -source $(ProjectDir)App_Data\Configs\Mip.Security.Sample.config -destination $(ProjectDir)App_Data\Configs\Mip.Security.config
$(SolutionDir)scripts\run-script.cmd$(SolutionDir)scripts\restore-default-file.ps1-source$(ProjectDir)App\u Data\Configs\Mip.Security.Sample.config-destination$(ProjectDir)App\u Data\Configs\Mip.Security.config
他正在运行64位PowerShell(这将是64位操作系统上的默认设置)。我已经了解了64位/32位的争议,这就是为什么我使用直接路径C:\windows\system32\。。。指向64位版本的powershell,而不是指向32位powershell的SysWOW64路径。它可能与使用“任意CPU”而不是x64的项目构建有关吗?您使用的是哪种版本的msbuild-64位还是32位?从一个获得虚拟化文件系统访问权限的32位应用程序中,路径C:\windows\system32`被重新映射到
C:\windows\SysWow64`。先生,这非常有趣,工作完美!(虽然不需要使用csc.exe-将目标平台设置为x64就足够了)您确定要在此处发布吗?这个问题是关于以64位而不是32位运行Powershell的-如何从那里获得输出重定向?因为如果试图创建CI环境,就会遇到这个问题。在CI环境中,我们需要能够将PS的输出作为构建的一部分。因此,我们需要修复这个线程以及输出重定向。非常好。关于CI,这是真的。但我认为这与这个问题有些无关,人们很可能找不到你的答案;-)这很好,我只是想加上它,因为这就是我自己来回答这个问题的原因。+1是非常优雅和正确的解决方案!谢谢分享。我的詹金斯奴隶拒绝以我尝试过的所有其他方式在64位进程中执行Powershell,但你的解决方案有效!