Rotaney
Rotaney

Reputation: 247

"Write-Error" (write in Powershell, used in C#) works BUT Write-Debug doesn´t work - Why?

I have written a program with C#, that creates a logfile and fills this by using log4net. This program starts powershell-scripts. The scripts use log4net, too. It works:

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

Now I want add to use the standard Write-Error, Write-Debug, etc. CMDlets in my Script.
(looks like here - answer of Hinek).

Powershell:
   Write-Warning "Write-Warning"      
  AND         
   Write-Error "Write-Error"

works, but the following doesn´t work:

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

... I get an error in my logfile, too. The error looks like this:

[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

(I think to have all namespaces.)

What the error-message means and what can I do again this?

thanks

Upvotes: 4

Views: 2429

Answers (3)

Rotaney
Rotaney

Reputation: 247

Now I had found the answer myself:

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

and this for write-debug:

Powershell-Code:

    usings ... 

    #set variable
    $DebugPreference

    #Now Write (-Debug) without Error
                    Write-Debug "Write-Debug"
                    Write-Warning "Write-Warning"
                    Write-Error "Ende --> Write-Error"

Upvotes: 1

Roman Kuzmin
Roman Kuzmin

Reputation: 42033

Here is a workaround solution: override the default command Write-Debug (which is actually not implemented) with a function:

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")
    }
}

In C# put this code into a string and invoke it once in the same runspace where the main script will be invoked. This “profile” code installs the global function Write-Debug which is semantically the same as the original cmdlet. Then, when the main code calls Write-Debug that function is called, not the default cmdlet.

P.S. I have not tried this way, I prefer to use my own host (see my other answer). But this way should work fine in many cases (not all, perhaps).

Upvotes: 3

Roman Kuzmin
Roman Kuzmin

Reputation: 42033

The message “the current host does not implement it” tells that you should provide a host that implements missed features. Presumably you should implement your own PSHost and PSHostUserInterface, at least what you really need there. In the latter class you implement methods like WriteDebugLine and WriteErrorLine. Then cmdlets Write-Warning and Write-Debug trigger that methods internally.

Complete example of a host with user interface and those methods: http://msdn.microsoft.com/en-us/library/ee706577(v=VS.85).aspx (Perhaps you don’t need most of other methods, provide some dummies then)

Upvotes: 4

Related Questions