我需要从应用程序(Core.exe)读取标准输出,该输出在同一进程中运行但在不同的appDomain中运行.在处理流程时重定向输出很容易,但appDomains概念对我来说是新的.
所以..我开始在isolataed appDomain中应用程序
new HostedApp("core", "Core.exe").Run();
class HostedApp
{
internal string DomainName;
internal string AssemblyName;
internal AppDomain Ad;
internal Thread AppThrd;
public HostedApp(string a_domain, string a_assemblyName)
{
DomainName = a_domain;
AssemblyName = a_assemblyName;
Ad = AppDomain.CreateDomain(a_domain);
}
public void Run()
{
AppThrd = new Thread(RunApp);
AppThrd.Start();
}
private void RunApp()
{
try
{
Ad.ExecuteAssembly(AssemblyName);
}
catch(Exception _ex)
{
MessageBox.Show("Unhandled exception\n" + _ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我试图重定向当前进程的Console.Out,假设如果应用程序共享相同的进程,则会有单个标准输出.
但它只显示默认的appDomain标准输出.
所以,总结一下,我需要访问另一个appDomain应用程序标准输出.或者可能有一种方法从"核心"appDomain调用位于默认appDomain中的方法?
小智 6
也许这可以帮到你.我使用这些类来监听远程AppDomains Trace.(Write/WriteLine)调用.
第一个类是一个允许我将TraceListen Write/WriteLine方法重定向到自定义委托的类.
public delegate void TraceWriterHandler(string message);
internal class SynchronizedTraceListener : TraceListener
{
private TraceWriterHandler messageHandler;
public SynchronizedTraceListener(TraceWriterHandler writeHandler)
{
messageHandler = writeHandler;
}
public override void Write(string message)
{
messageHandler(message);
}
public override void WriteLine(string message)
{
messageHandler(message + System.Environment.NewLine);
}
}
Run Code Online (Sandbox Code Playgroud)
然后是我的远程AppDomain跟踪侦听器类的核心.这是棘手的部分.我会尽量不弄乱这个解释.这对我来说很棘手,但在这里.
笔记:
[Serializable]
public sealed class CrossDomainTracer : MarshalByRefObject
{
private CrossDomainTracer remoteTracer;
private SynchronizedTraceListener remoteListener;
public CrossDomainTracer()
{
}
public CrossDomainTracer(AppDomain farDomain)
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
this.remoteTracer = farDomain.CreateInstanceFrom(Assembly.GetExecutingAssembly().Location, typeof(CrossDomainTracer).FullName).Unwrap() as CrossDomainTracer;
AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
if (remoteTracer != null)
{
remoteTracer.StartListening(this);
}
}
public void StartListening(CrossDomainTracer farTracer)
{
this.remoteTracer = farTracer;
this.remoteListener = new SynchronizedTraceListener(new TraceWriterHandler(Write));
Trace.Listeners.Add(this.remoteListener);
}
public void Write(string message)
{
this.remoteTracer.RemoteWrite("AppDomain(" + AppDomain.CurrentDomain.Id.ToString() +") " + message);
}
public void RemoteWrite(string message)
{
Trace.Write(message);
}
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
try
{
Assembly assembly = System.Reflection.Assembly.Load(args.Name);
if (assembly != null)
{
return assembly;
}
}
catch { }
// Try to load by assembly fullname (path to file)
string[] Parts = args.Name.Split(',');
string File = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + Parts[0].Trim() + ".dll";
return System.Reflection.Assembly.LoadFrom(File);
}
}
Run Code Online (Sandbox Code Playgroud)
Finnaly你可以整齐地将所有这些包装在静态类中.
public static class CrossDomainTrace
{
public static void StartListening(AppDomain remoteDomain)
{
new CrossDomainTracer(remoteDomain);
}
}
Run Code Online (Sandbox Code Playgroud)
通过在应用程序中执行此操作,该应用程序将注册远程跟踪按摩.
CrossDomainTrace.StartListening(theFarAppDomain);
Run Code Online (Sandbox Code Playgroud)
剩下的唯一事情就是将TraceListner添加到此方的Trace.Listeners集合中,以便随意使用消息.
希望能帮助到你.