在使用参数构建后调用powershell脚本

时间:2011-02-15 16:46:03

标签: visual-studio-2010 powershell sharepoint-2010 build-process

我试图让Powershell在post post中运行我的PS脚本 - 但不知何故它不能像它应该的那样工作:

在Post-Build中执行以下命令:

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

(插入换行符以便更好地阅读)

该命令成功执行powershell脚本,但它不能执行的操作是在(Output from Build)中运行命令: Rund Post-Build Command:

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 Snap-In。

  • 从cmd运行powershell C:\ path \ CreateSite.ps1 auto时 - 一切正常。
  • 打开powershell.exe并自动运行C:\ path \ CreateSite.ps1时 - 一切正常。
  • 右键单击CreateSite.ps1 - &gt;与powershell一起运行 - 一切正常。

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

我如何才能运行darn脚本(让它包含PSSnapIn)在Visual Studio后期版本中传递一个参数?

5 个答案:

答案 0 :(得分:16)

(这个帖子不是新的,但是我从谷歌来到这里,所以我认为分享我发现的解决方案会让其他人感兴趣)

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

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

答案 1 :(得分:6)

由于文件系统虚拟化,您无法从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

然后,从您的构建后事件执行此启动程序exe,向其传递要调用64位PowerShell的参数。此外,使用PowerShell 2.0,我建议使用File参数来执行脚本,例如:

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

那就是说,肯定还有其他一些方法(实用程序)可以从64位进程启动exes。

答案 2 :(得分:1)

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

答案 3 :(得分: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

进行通话

答案 4 :(得分:1)

使用以下内容添加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 %*

以这种方式从构建事件中调用它:


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