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