التقاط Powershell الانتاج في C# بعد خط أنابيب.الاحتجاج يلقي

StackOverflow https://stackoverflow.com/questions/1233640

  •  22-07-2019
  •  | 
  •  

سؤال

أنا أجري اختبار البرنامج النصي Powershell من C# التطبيق.السيناريو يمكن أن تفشل بسبب سوء cmdlet الذي يسبب الأنابيب.الاحتجاج() رمي استثناء.

أنا قادرة على التقاط كافة المعلومات التي أحتاجها حول استثناء ، ولكن أود أن تكون قادرة على عرض البرنامج النصي الإخراج يصل إلى تلك النقطة.لم يكن لدي أي حظ لأن النتائج تظهر أن تكون فارغة عندما يتم طرح استثناء.

هل هناك شيء أنا في عداد المفقودين ؟ وذلك بفضل!

m_Runspace = RunspaceFactory.CreateRunspace();
m_Runspace.Open();
Pipeline pipe = m_Runspace.CreatePipeline();
pipe.Commands.AddScript(File.ReadAllText(ScriptFile));
pipe.Commands.Add("Out-String");
try {
   results = pipe.Invoke();
}
catch (System.Exception)
{
   m_Runspace.Close();
   // How can I get to the Powershell output that comes before the exception?
}
هل كانت مفيدة؟

المحلول 2

وكان الحل انتهى بي الأمر باستخدام لتنفيذ PSHost منطقتنا للتعامل مع الانتاج بوويرشيل ل. المعلومات الأولية لهذا جاءت من <لأ href = "http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost. ASPX "يختلط =" noreferrer "> http://community.bartdesmet.net/blogs/bart/archive/2008/07/06/windows-powershell-through-ironruby-writing-a-custom-pshost.aspx في القسم "بناء المضيف PS العرف".

في حالتي لم تتطلب استخدام PSHostRawUserInterface مخصصة أيضا.

إليك لمحة سريعة عن ما تم إنجازه. لقد سردت فقط وظيفة I implimented في الواقع، ولكن هناك العديد من التي هي مجرد احتواء رمي NotImplementedException جديد ()؛

private class myPSHost : PSHost
{
   (Same as what the above link mentions)
}
private class myPSHostUI : PSHostUserInterface
{
   private myPSHostRawUI rawui = new myPSHostRawUI();

   public override void Write // all variations
   public override PSHostRawUserInterface RawUI { get { return rawui; } }

}
private class myPSHostRawUI : PSHostRawUserInterface
{
   public override ConsoleColor ForegroundColor
   public override ConsoleColor BackgroundColor
   public override Size BufferSize
}

نصائح أخرى

ولست متأكدا إذا كان هذا مفيد. وأنا على التخمين كنت تقوم بتشغيل V1. هذا النهج V2 لا رمي وطباعة النتيجة:

Hello World
67 errors

string script = @"
  'Hello World'
  ps | % {
    $_.name | out-string1
  }
";

PowerShell powerShell = PowerShell.Create();

powerShell.AddScript(script);
var results = powerShell.Invoke();

foreach (var item in results)
{
  Console.WriteLine(item);
}

if (powerShell.Streams.Error.Count > 0)
{
  Console.WriteLine("{0} errors", powerShell.Streams.Error.Count);
}

لدي نفس المشكلة.أسهل طريقة للحصول على الإخراج عند الأنابيب.الاحتجاج() يلقي استثناء هو استخدام الاحتجاج(IEnumerable المدخلات ، IList الإخراج)

مثال يوضح كيفية الحصول على جميع إخراج خطأ أو تراجع.... الخفي الترتيب الصحيح

النصي PowerShell

Write-Output "Hello world" 
Write-Error "Some error"
Write-Warning "Some warning"
throw "Some exception"

C#

List<string> RunLog = new List<string>(); 

using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())

{
    psInstance.AddScript(_Script);

psInstance.Streams.Error.DataAdded += (sender, args) =>
{
    ErrorRecord err = ((PSDataCollection<ErrorRecord>)sender)[args.Index];
    RunLog.Add($"ERROR: {err}");
};

psInstance.Streams.Warning.DataAdded += (sender, args) =>
{
    WarningRecord warning = ((PSDataCollection<WarningRecord>)sender)[args.Index];
    RunLog.Add($"WARNING: {warning}");
};

... etc ...

var result = new PSDataCollection<PSObject>();
result.DataAdded += (sender, args) =>
{
    PSObject output = ((PSDataCollection<PSObject>)sender)[args.Index];
    RunLog.Add($"OUTPUT: {output}");
};

try
{
    psInstance.Invoke(null, result);
}
catch(Exception ex)
{
    RunLog.Add($"EXCEPTION: {ex.Message}");
}                                                
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top