2011-11-07 1 views
2

Est-ce considéré comme une mauvaise pratique (ou existe-t-il des raisons spécifiques de ne pas créer un RunSpace dans une cmdlet C# personnalisée? Par exemple, j'ai une Cmdlet personnalisée, comme ci-dessous et j'ai besoin d'appeler une applet de commande existante et je me demande s'il y aura des problèmes de threading ou autres avec cela.Est-ce une mauvaise pratique de créer un nouvel RunSpace à partir d'une cmdlet C# personnalisée?

public class SPCmdletNewBusinessSite : SPNewCmdletBase<SPSite> 
    { 

... 
    private void ExecuteRunspaceCommand() 
      { 
       Runspace runspace = RunspaceFactory.CreateRunspace(); 
       PSSnapInException snapInError; 
       runspace.RunspaceConfiguration.AddPSSnapIn("Microsoft.SharePoint.PowerShell", out snapInError); 
       runspace.ThreadOptions = PSThreadOptions.Default; 
       runspace.Open(); 

       Pipeline pipeline = runspace.CreatePipeline(); 

       Command newSiteProc = new Command("New-SPSite"); 
       newSiteProc.Parameters.Add(new CommandParameter("Url", "http://goober-dc/9393")); 
       newSiteProc.Parameters.Add(new CommandParameter("OwnerAlias", "GOOBER\\Administrator")); 
       newSiteProc.Parameters.Add(new CommandParameter("Template", "STS#1")); 
       newSiteProc.Parameters.Add(new CommandParameter("Language", "1033")); 
       newSiteProc.Parameters.Add(new CommandParameter("ContentDatabase", "Site_Specific_ContentDB")); 

       pipeline.Commands.Add(newSiteProc); 
       Collection<PSObject> results = new Collection<PSObject>(); 

       results = pipeline.Invoke(); 
       foreach (PSObject obj in results) 
       { 
        base.WriteObject(((SPSite)obj.BaseObject).RootWeb.Title); 
       }     

      } 
} 

Plus précisément, je veux créer un SharePoint 2010 SPSite et spécifiez une base de données de contenu spécifique pour la SPSite. Il existe une surcharge pour SPSitesCollection.Add() qui accepte un SPContentDatabase en tant que paramètre, mais il s'agit d'une méthode interne. Je veux créer RunSpace pour activer l'appel de l'applet de commande New-SPSite (ce qui permet de spécifier un nouveau contenu db) et donc pouvoir créer le site avec une base de données de contenu spécifique.

J'ai trouvé http://msdn.microsoft.com/en-us/library/ms714873(v=VS.85).aspx indique que vous pouvez appeler des applets de commande à l'intérieur de cmdlets, mais que New-SPSite (classe SPCmdletNewSite réelle) est également interne et ne peut pas être appelée directement.

+0

On ne sait pas pourquoi vous avez besoin d'un espace d'exécution supplémentaire. À moins que vous ne vouliez garder l'actuel sans le composant logiciel enfichable supplémentaire, est-ce la raison? Est-ce le vrai code ou pseudo code? Dans le dernier cas, quelle partie est pseudo? En particulier, SPSitesCollection.Add() est mentionné mais il n'est pas utilisé dans le code (désolé si je manque quelque chose). –

+0

En répondant à la question dans le titre (je ne suis pas sûr que ce soit la question qui vous intéresse), je ne pense pas que ce soit une mauvaise pratique s'il y a des raisons de créer de nouveaux espaces de course. Sans raisons, c'est une mauvaise pratique, les nouveaux runspaces ne sont pas bon marché. –

+0

Merci Roman - J'essaie d'appeler l'applet de commande New-SPSite dont l'implémentation de classe réelle (en C#) est interne scellée, "classe scellée interne SPCmdletNewSite: SPNewCmdletBase ". Comme je ne peux pas appeler Invoke directement sur la classe d'applets de commande, j'essaie de déterminer les problèmes que je pourrais rencontrer ou créer en appelant l'applet de commande dans un RunSpace distinct comme décrit ci-dessus. S'il y a d'autres alternatives, s'il vous plaît faites le moi savoir. Je suis relativement nouveau dans la création de nouvelles cmdlets personnalisées en C#. –

Répondre

2

Si vous souhaitez appeler une autre cmdlet à l'intérieur d'une cmdlet, la pratique habituelle consiste à utiliser un pipeline imbriqué et non un nouvel espace d'exécution. Cela vous permet d'utiliser la portée de la cmdlet, ce qui vous donne accès aux mêmes variables et au même contexte. Un nouvel espace d'exécution est complètement isolé et est plus lourd en conséquence, mais peut être souhaité si vous ne polluez pas la portée d'appel. Je pense que vous voulez probablement un pipeline imbriqué afin de ne pas avoir à recharger le snapin sharepoint (je présume qu'il est déjà chargé lorsque vous appelez votre nouvelle cmdlet sharepoint.)

Vous pouvez utiliser cette méthode depuis votre cmdlet. C'est un pipeline imbriqué car votre commande est déjà en cours d'exécution dans un pipeline.

var pipe = Runspace.DefaultRunspace.CreateNestedPipeline(...); 
pipe.Invoke() 

http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspace.createnestedpipeline(v=VS.85).aspx

+0

Génial! Merci pour l'info et pour le lien pour m'éduquer davantage. –

Questions connexes