&引用;“写入错误”;(在Powershell中写入,在C#中使用)可以工作,但写入调试不起作用´;不行-为什么?
我用C#编写了一个程序,它创建了一个日志文件,并使用log4net来填充它。此程序启动powershell脚本。脚本也使用log4net。 有效:&引用;“写入错误”;(在Powershell中写入,在C#中使用)可以工作,但写入调试不起作用´;不行-为什么?,c#,windows,logging,powershell,windows-xp,C#,Windows,Logging,Powershell,Windows Xp,我用C#编写了一个程序,它创建了一个日志文件,并使用log4net来填充它。此程序启动powershell脚本。脚本也使用log4net。 有效: > C#: > ps.Runspace.SessionStateProxy.SetVariable("myMethod",(Action<Level,string>)myMethod); > ps.AddCommand(System.IO.Path.Combine(pathScripts, testSkripte[
> C#:
> ps.Runspace.SessionStateProxy.SetVariable("myMethod",(Action<Level,string>)myMethod);
> ps.AddCommand(System.IO.Path.Combine(pathScripts, testSkripte[i].ToString()));
> ps.Invoke();
> Powershell:
> $ScriptLog.Invoke([log4net.Core.Level]::Debug, "TestFile_Debug")
> $ScriptLog.Invoke([log4net.Core.Level]::Warn, "TestFile_Warn") $ScriptLog
> $ScriptLog.Invoke([log4net.Core.Level]::Error, "TestFile_Error")
有效,但以下情况不起作用:
Write-Debug "Write-Debug" (I don´t get an item in my logfile) OR
Write-Debug "Write-Debug" -debug (for this I get an item in my logfile, but ...)
。。。我的日志文件也有错误。错误如下所示:
[2010-10-22 13:10:58,097] DEBUG : Write-Debug
[2010-10-22 13:10:58,113] ERROR : Cannot invoke this function because the current
host does not implement it
(我认为应该拥有所有的名称空间。)
错误消息的含义是什么?我可以再次执行此操作吗
谢谢消息“当前主机未实现它”告诉您应该提供一台实现遗漏功能的主机。大概您应该实现自己的
PSHost
和PSHostUserInterface
,至少是您真正需要的。在后一个类中,您实现了WriteDebugLine
和WriteErrorLine
等方法。然后cmdletWrite Warning
和Write Debug
触发内部方法
具有用户界面和这些方法的主机的完整示例:
(也许你不需要大多数其他方法,那么就提供一些傻瓜)这里有一个解决方案:用一个函数覆盖默认命令
Write Debug
(实际上没有实现):
function global:Write-Debug
(
[string]
$Message,
[switch]
$Debug
)
{
# check both the $Debug switch and the $DebugPreference variable:
if ($Debug -or ($DebugPreference -ne 'SilentlyContinue')) {
# do job; in this demo just write to the console:
[Console]::WriteLine("DEBUG: $Message")
}
}
在C#中,将此代码放入字符串中,并在调用主脚本的同一运行空间中调用它一次。此“配置文件”代码安装全局函数Write Debug
,其语义与原始cmdlet相同。然后,当主代码调用Write Debug
时,将调用该函数,而不是默认cmdlet
另外,我没有尝试过这种方式,我更喜欢使用自己的主机(见我的其他答案)。但是这种方法在很多情况下(也许不是所有情况下)都很有效。现在我自己找到了答案:
C#-Code:
using (ps = PowerShell.Create())
{
int a = testSkripte.Count;
for (int i = 0; i < a; i++)
{
ps.Runspace.SessionStateProxy.SetVariable("portalpfad", pathExecuteScript);
ps.Runspace.SessionStateProxy.SetVariable("ScriptLog", (Action<Level, string>)ScriptLog);
//add following row:
ps.Runspace.SessionStateProxy.SetVariable("DebugPreference", "Continue");
ps.AddCommand(System.IO.Path.Combine(pathScripts, testSkripte[i].ToString()));
ps.Streams.Debug.DataAdded += new EventHandler<DataAddedEventArgs>(Debug_DataAdded);
ps.Streams.Warning.DataAdded += new EventHandler<DataAddedEventArgs>(Warning_DataAdded);
ps.Streams.Error.DataAdded += new EventHandler<DataAddedEventArgs>(Error_DataAdded);
ps.Invoke();
}
好啊现在我必须验证你的建议。我的意思是这很迂回,因为我需要三个类,它们有很多我不需要的方法。没有捷径了吗?(我考虑了一些参数,因为errormessages和warnings都有效。你还有其他想法吗?谢谢。@Roman肯定是对的,没有任何快捷方式。PowerShell宿主API非常复杂。你要做的只是提供虚拟方法(抛出new NotImplementedException)所有你不需要的东西。@Rotaney:你需要两个类(主机和用户界面)。“第三类”是您的应用程序,您已经拥有了它。这是一个很好的发现。不过,您的应用程序看起来并不是那么简单。自定义主机方法是可伸缩的,因此对于非平凡的解决方案更具吸引力。想象一下:明天您的工作脚本想要调用
编写进度
,读取主机
,等等。拥有一个自定义主机,您将添加帽子还没有错过的功能相对容易。
C#-Code:
using (ps = PowerShell.Create())
{
int a = testSkripte.Count;
for (int i = 0; i < a; i++)
{
ps.Runspace.SessionStateProxy.SetVariable("portalpfad", pathExecuteScript);
ps.Runspace.SessionStateProxy.SetVariable("ScriptLog", (Action<Level, string>)ScriptLog);
//add following row:
ps.Runspace.SessionStateProxy.SetVariable("DebugPreference", "Continue");
ps.AddCommand(System.IO.Path.Combine(pathScripts, testSkripte[i].ToString()));
ps.Streams.Debug.DataAdded += new EventHandler<DataAddedEventArgs>(Debug_DataAdded);
ps.Streams.Warning.DataAdded += new EventHandler<DataAddedEventArgs>(Warning_DataAdded);
ps.Streams.Error.DataAdded += new EventHandler<DataAddedEventArgs>(Error_DataAdded);
ps.Invoke();
}
Powershell-Code:
usings ...
#set variable
$DebugPreference
#Now Write (-Debug) without Error
Write-Debug "Write-Debug"
Write-Warning "Write-Warning"
Write-Error "Ende --> Write-Error"