【问题标题】:Calling Powershell command using C#使用 C# 调用 Powershell 命令
【发布时间】:2014-12-01 19:35:25
【问题描述】:

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

//命令

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();
        }

【问题讨论】:

    标签: powershell c#-4.0 process


    【解决方案1】:

    一旦proc.WaitForExit() 完成,process.HasExited 将始终为true,因此您的while 循环将永远不会进入,output 将具有其初始值。您不需要循环,只需在进程退出后读取输出即可:

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

    我假设您有特定的原因想要在子进程中执行 PowerShell 代码。否则,更好的方法是来自@Keith Hill 的答案,或者只是将您的 PowerShell 代码转换为 C# 并直接从您的应用程序查询数据。添加对System.Management.Automation 程序集的引用以及System.Collections.GenericSystem.Linq 命名空间的一些using 语句后,直接翻译将类似于...

    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);
    

    【讨论】:

    • 非常感谢,并为我的小 Powershell 体验感到抱歉:这是我得到的异常,异常:您不能在空值表达式上调用方法。\n在 line:3 char: 50\n+ $websvcs = $farm.Services |其中 -FilterScript {$_.GetType() -eq
    【解决方案2】:

    我会为此使用 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
    

    【讨论】:

    • 非常感谢,并为我的小 Powershell 体验感到抱歉:这是我得到的异常,异常:您不能在空值表达式上调用方法。\n在 line:3 char: 50\n+ $websvcs = $farm.Services |其中 -FilterScript {$_.GetType() -eq
    【解决方案3】:
    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());
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 2016-12-12
      • 1970-01-01
      • 2015-04-22
      • 2015-03-25
      相关资源
      最近更新 更多