2014-12-01 61 views
0

我试着用C#执行这个PowerShell命令,并等待输出,这是我域中的SharePoint网站列表! PowerShell本身工作正常,但使用C#进程调用它,不会等待输出! 任何意见或建议表示赞赏。使用C调用Powershell命令#

//命令

string cmd = @"[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SharePoint') >  $null 
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local 
$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]} 
$webapps = @() 
foreach ($websvc in $websvcs) { 
     foreach ($webapp in $websvc.WebApplications) { 
       foreach ($site in $webapp.Sites) { 
       $site.URL 
       } 
     } 
} "; 

// C#的过程!

 Process proc = new Process(); 
     proc.StartInfo = new ProcessStartInfo("powershell.exe", cmd); 
     proc.Start(); 
     proc.StartInfo.RedirectStandardOutput = true; 
     proc.StartInfo.UseShellExecute = false; 
     proc.WaitForExit(); 
     string output = ""; 
     while (!proc.HasExited) 
     { 
      output += proc.StandardOutput.ReadToEnd(); 
     } 

回答

0

process.HasExited永远是true一次proc.WaitForExit()已完成,因此您的while循环将永远不会输入并且output将具有其初始值。你并不需要循环,可以改为仅仅读取输出,一旦进程已退出:

proc.WaitForExit(); 
string output = proc.StandardOutput.ReadToEnd(); 

我假设你有想在一个子进程来执行PowerShell代码具体原因。否则,更好的方法是从@Keith Hill得到答案,或者只是将您的PowerShell代码转换为C#并直接从您的应用程序查询数据。增加了​​集的引用以及一些using报表。System.Collections.GenericSystem.Linq命名空间后,直接翻译会是这样的......

var farm = Microsoft.SharePoint.Administration.SPFarm.Local; 
var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>(); 
var siteUrls = new List<string>(); 

foreach (var websvc in websvcs) 
    foreach (var webapp in websvc.WebApplications) 
     foreach (var site in webapp.Sites) 
      siteUrls.Add(site.Url); 

...和更LINQified办法可以...

var farm = Microsoft.SharePoint.Administration.SPFarm.Local; 
var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>(); 
var siteUrls = websvcs 
    .SelectMany(websvc => websvc.WebApplications) 
    .SelectMany(webapp => webapp.Sites) 
    .Select(site => site.Url); 
+0

非常感谢:) – 2014-12-02 22:02:25

+0

@KeithHill非常感谢:) – 2014-12-02 22:02:43

+0

非常感谢,对不起我的小PowerShell体验: 这是我得到的异常, 例外:您无法在空值表达式上调用方法。\ n行:3 char:50 \ n + $ websvcs = $ farm.Services | -FilterScript {$ _。GetType()-eq – 2014-12-02 23:03:27

0

我会为此使用PowerShell自动化引擎。在您的C#项目中,参考C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0的程序集System.Management.Automation.dll。然后在你的代码试试这个:

string cmd = "your commands"; 
string output = ""; 
using (var ps = PowerShell.Create()) 
{ 
    ps.AddScript(cmd); 
    var results = ps.Invoke(); 
    foreach (var result in results) 
    { 
     output += result.ToString(); 
    } 
} 

如果你只在你的输出获得的类型名称,改变这一行:

$site.URL 

到:

$site.URL | Out-String 
+0

非常感谢和抱歉我的小PowerShell的经验: 这是我得到的例外, 例外:不能CA对一个空值表达式使用方法。\ n行:3 char:50 \ n + $ websvcs = $ farm.Services |其中-FilterScript {$ _。GetType()-eq – 2014-12-02 23:02:38

0
var farm = Microsoft.SharePoint.Administration.SPFarm.Local; 
     var websvcs = farm.Services.OfType<Microsoft.SharePoint.Administration.SPWebService>(); 
     var siteUrls = websvcs 
      .SelectMany(websvc => websvc.WebApplications) 
      .SelectMany(webapp => webapp.Sites) 
      .Select(site => site.Url); 

     foreach (var i in siteUrls) 
     { 
      Console.WriteLine(i.ToString()); 
     }