Question Customize output in hosted CLR (.NET)

kosmosec

Member
Joined
Sep 16, 2021
Messages
18
Programming Experience
5-10
Hi, I'm hosting CLR in Golang program (but it doesn't matter where). Is the way to configure CLR to capture output from .NET assembly executed in my in-process CLR runtime straight into a file? I run .NET assembly in hosted CLR and I want to capture this output straight to the file (or some buffer).
 
Say what? So if an application is outputting to a database, or to a TCP channel, or the screen GUI, or a printer, or a USB port, or a specific file, or the Windows registry, you want to somehow capture that output and put that into a file? What format would that file contents be?

Are you just talking about standard console output?
 
Oh, srr. Those applications only print on standard console output using Console.WriteLine and so on. The format is just the text like Console.WriteLine("test..."). I know I can use SetStdHandle but if I run two applications in this hosted CLR the output will be mixed. I want to run many programs at the same time and I want to capture output for each specific application.
 
Can those "applications" be re-written to accept a TextWriter for them to write to instead of the Console?

The common theme in various StackOverflow and MSDN forum answers is that you cannot capture the console output, and that the best approach is to pass in a TextWriter for the various objects to use.
 
No, I want to treat those applications as black-box and don't want to re-write. I thought that CLR provide some methods to manipulate stdout.
 
Yes, you manipulate the standard output by using the Console object from within the current running C# program. Another alternative is to redirect output while using the Process.Start() method.

The issue is that what you are trying to do is from the hosting side while hosting from within Go. I would assume that when you implement the hosting interfaces that one of the interfaces you would implement covers I/O, but I don't really know since I've never had to host the CLR.
 
"I would assume that when you implement the hosting interfaces that one of the interfaces you would implement covers I/O" indeed, I thought the same but I can't find the proper interface :D
 
I did a quick browse of all the IHost* interfaces and nothing jumped out at me as something that seemed like it was for controlling console IO. I saw something about IO Completion management, but it looked like it was related to the other thread synchronization management hosting interfaces.

As a quick aside, although this Code Project talking about how to do things in C++, it seems to have the concepts that would work in Go as well:

 
Wow thanks, this article is really interesting and it potentially solves my problem but I have no idea how to tell the CLR to run or share the newly created console ;/ It works when I run something from the command line using CrateProcess() but I can't because I initialize the CLR directly in Go.
 
You can do this with multiple AppDomains (CreateDomain), each using DoCallback method where you redirect output with Console.SetOut and run the library method.
 
Oo, interesting. I don't know the C# well but sounds like it could works. Hmm, I will look at this and figure out how to implement it in Golang.
 
The callback is the secondary appdomain where you can call your app in isolation. There is always a default appdomain that any .Net code runs in. If you need to pass data between them use SetData/GetData methods.
 
I create default app domain using ICorRuntimeHost -> GetDefaultDomain(), on default app domain I run Load_3 (then find entrypoint) and finally on MethodInfo I run Invoke_3.
So, I should create appdomain in callback (not default app domain) and in the callback run Invoke_3. In the default appdomain which "wraps" callback I should use Console.SetOut method? Am I right? If yes, I don't know if I can run Console.SetOut from Golang.

This repo is a simple example of hosting CLR in Go - GitHub - ropnop/go-clr: A PoC package for hosting the CLR and executing .NET from Go It is not my repo but the core is almost the same as in my code.
 
The console is isolated in each AppDomain. Since you want to call multiple 'app' methods simultaneously that outputs to console, and don't want the output to be mixed, the suggestion is to call each method in it's own AppDomain. Console.Setout is suggested to redirect the output of your 'app' methods to any suitable TextWriter, this is done in each AppDomain where you want the output redirected.
C#:
default domain (the main .Net code running)
> CreateDomain>DoCallback 
> the callback: Console.SetOut , call method that outputs to console
 
Back
Top Bottom