التقاط Powershell الانتاج في C# بعد خط أنابيب.الاحتجاج يلقي
-
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}");
}
}