Appeler le script powershell en post-construit avec des paramètres
J'essaie D'obtenir de Powershell d'exécuter mon script PS dans post built - mais d'une certaine façon, il ne fonctionne pas comme il est supposé le faire:
commande suivante dans Post-Build:
C:WINDOWSsystem32windowspowershell.0powershell.exe
-Command "& $(MSBuildProjectDirectory)CreateSite.ps1 'auto'"
(saut de ligne inséré pour une meilleure lecture)
la commande exécute le script powershell avec succès, mais ce qu'elle ne peut pas faire c'est exécuter les commandes à l'intérieur (sortie de Build): Commande Après Exécution:
Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2
At C:pathCreateSite.ps1:4 char:
38
+ Add-PsSnapin <<<< Microsoft.SharePoint.PowerShell}
+ CategoryInfo : InvalidArgument: (Microsoft.SharePoint.PowerShell:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand
et suivants qui sont de nombreuses erreurs parce que toutes les commandes subséquentes ont besoin du Snap-In Sharepoint.
- lors de l'exécution powershell C:pathCreateSite.ps1 auto de cmd-tout fonctionne.
- en ouvrant powershell.exe et running C:pathCreateSite.ps1 auto-tout fonctionne.
- Quand un clic droit CreateSite.ps1 --> exécuter avec powershell, tout fonctionne.
la ligne pertinente dans le script est simplement Add-PsSnapin Microsoft.SharePoint.PowerShell
.
Comment puis-je lancer le script (et le faire inclure le PSSnapIn) en lui passant un paramètre dans Visual Studio post-build?
5 réponses
en raison de la virtualisation du système de fichiers, vous ne pouvez pas vraiment spécifier le chemin vers la version 64 bits de PowerShell à partir d'un processus 32 bits (C'est à dire Visual Studio-qui héberge le moteur msbuild). Une façon de contourner ce problème est de créer un lanceur 64 bits qui tourne en 64 bits et lancera la version 64 bits de PowerShell. Voici un simple programme C# qui fera ceci:
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;
}
}
assurez-vous de compiler ceci en 64-bit comme ceci:
csc .\PowerShell64.cs /platform:x64
ensuite, à partir de votre événement post-build, exécutez ce lanceur exe en lui passant les paramètres avec lesquels vous voulez invoquer PowerShell 64 bits. En outre, avec PowerShell 2.0, je recommande d'utiliser le paramètre File
pour exécuter un script par exemple:
c:\path\PowerShell64.exe -File "$(MSBuildProjectDirectory)\CreateSite.ps1" auto
cela dit, sûrement il doit y avoir une autre façon (utilitaire) qui lance exes à partir d'un processus 64 bits.
(ce fil n'est pas nouveau, mais je suis arrivé ici de Google, donc j'ai pensé que le partage de la solution que j'ai trouvé serait intéressant pour d'autres)
j'ai essayé de changer le chemin vers powershell.exe to " %WINDIR % \SysNative\WindowsPowerShell\v1.0\powershell.exe" et ça a fonctionné parfaitement. La version 64 bits est appelée à partir de L'événement post Build et elle ajoute avec succès le snapin SharePoint.
crédits pour cet article: http://msdn.microsoft.com/en-us/library/ff798298.aspx , "à l'Aide de Windows PowerShell Scripts pour Automatiser des Tâches dans Visual Studio".
lorsque vous exécutez vous script directement, vous utilisez probablement 32bit PowerShell et dans votre script msbuild 64bit ou vice versa. Aussi jeter un oeil à Erreur msg: "aucun snap-ins ont été enregistrés pour Windows PowerShell version 2." .
une variante légèrement meilleure de la redirection de sortie:
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();
}
}
}
appel avec sh64 powershell -File ./buildscripts/deploy.ps1 -Ex RemoteSigned
ajouter cmd-file (Ex: run-script.cmd) avec ce contenu:
@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 %*
et l'appeler de l'événement de construction d'une telle manière:
$(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