"Write-Error" (the Powershell entry used in C #) works, BUT write-debugging does not work - Why?

I wrote a C # program that creates a log file and populates it with log4net. This program runs powershell scripts. Scripts also use log4net. He 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 to add use the standard Write-Error, Write-Debug, etc. CMDlets in my Script.
( looks here - Heineck's answer).

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

works, but the following does not 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 also get an error in my log file. 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 all namespaces.)

What does the error message mean and what can I do again?

thanks

+4
source share
3 answers

Now I myself found the answer:

 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 is 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" 
+1
source

The message "the current host does not implement it" indicates that you must provide a host that implements the missed functions. Presumably, you should implement your own PSHost and PSHostUserInterface , at least what you really need there. In the last class, you implement methods like WriteDebugLine and WriteErrorLine . Then cmdlets Write-Warning and Write-Debug start these methods internally.

A complete host example with a user interface and these methods: http://msdn.microsoft.com/en-us/library/ee706577(v=VS.85).aspx (You may not need most of the other methods, then give some dummies )

+4
source

Here is a workaround: override the default Write-Debug command (which is not actually implemented) using the 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 in a line and call it once in the same workspace where the main script will be called. This "profile" code sets the global Write-Debug function, which semantically matches the original cmdlet. Then, when the main code calls Write-Debug this function, not the default cmdlet.

PS I have not tried this path, I prefer to use my own host (see My other answer). But this method should work fine in many cases (not everything is possible).

+3
source

All Articles