Reputation: 247
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
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
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
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