7

我试图让PowerShell来运行我的PS脚本后建 - 但不知何故,它不工作像它应该是:呼叫PowerShell脚本后建有参数

下面的命令在生成后:

C:\WINDOWS\system32\windowspowershell\1.0\powershell.exe 
    -Command "& $(MSBuildProjectDirectory)\CreateSite.ps1 'auto'" 

(为便于阅读插入换行符)

命令成功地执行PowerShell脚本,但它不能做的就是运行(输出版本)中的命令: Rund Post-Build命令:

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 

而后面是很多错误,因为所有后续命令都需要Sharepoint管理单元。

  • 从cmd运行powershell C:\ path \ CreateSite.ps1 auto - 一切正常。
  • 当打开powershell.exe并运行C:\ path \ CreateSite.ps1自动 - 一切正常。
  • 右键单击CreateSite.ps1 - >使用powershell运行 - 一切正常。

脚本中的相关行仅仅是Add-PsSnapin Microsoft.SharePoint.PowerShell

我怎样才能运行darn脚本(并让它包括PSSnapIn)在Visual Studio后构建中传递参数?

回答

6

由于文件系统虚拟化,您无法真正从32位进程(即Visual Studio - 承载msbuild引擎)指定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 

然后,从生成后事件执行该发射器的exe传递您想要用64位PowerShell调用的参数。此外,使用PowerShell 2.0,我会建议使用File参数来执行脚本例如为:

c:\path\PowerShell64.exe -File "$(MSBuildProjectDirectory)\CreateSite.ps1" auto 

这就是说,肯定必须有从64位进程启动的EXE一些其他的方式(实用)。

1

当您直接运行脚本时,可能使用32位PowerShell,并在msbuild脚本中使用64位,反之亦然。也看看Error msg: “No snap-ins have been registered for Windows PowerShell version 2.”

+0

是的,在SharePoint管理单元是64位。 +1 – x0n 2011-02-15 20:51:06

+1

他正在运行64位PowerShell(这将成为64位操作系统的默认设置)。 – JasonMArcher 2011-02-15 21:06:17

+0

我已阅读有关64位/ 32位争议,这就是为什么我使用直接路径C:\ windows \ system32 \ ...到64位版本powershell而不是SysWOW64路径导致32位PowerShell。这与“任何CPU”而不是x64的项目建筑有什么关系? – 2011-02-15 21:28:50

1

输出重定向的稍微好一点的变体:

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

16

(此线是不是新的,但我从谷歌来到这里,所以我想分享我找到了解决办法对其他人很有意思)

我试着将powershell.exe的路径改为“%WINDIR%\ SysNative \ WindowsPowerShell \ v1.0 \ powershell.exe”,它工作的很完美。 64位版本从Post Build事件中调用,并成功添加了SharePoint管理单元。

对本文的支持:http://msdn.microsoft.com/en-us/library/ff798298.aspx“使用Windows PowerShell脚本在Visual Studio中自动执行任务”。

1

添加CMD-文件(例如运行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 %* 

和从生成事件以这样的方式把它叫做:

 

    $(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