&引用;“写入错误”;(在Powershell中写入,在C#中使用)可以工作,但写入调试不起作用´;不行-为什么?

&引用;“写入错误”;(在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#编写了一个程序,它创建了一个日志文件,并使用log4net来填充它。此程序启动powershell脚本。脚本也使用log4net。 有效:

> 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
等方法。然后cmdlet
Write 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"