C# 在AppDomain中启动.NET进程

C# 在AppDomain中启动.NET进程,c#,process,appdomain,C#,Process,Appdomain,我问题的标题可能已经暴露了一个事实,那就是我不确定我想要什么,因为它可能没有意义 对于一个项目,我希望能够在我的应用程序中运行可执行文件,同时重定向它们的标准输入和输出,以便我的应用程序可以通过这些流与它们通信 同时,我不想让这些可执行文件执行某些操作,比如使用网络,或者在它们自己的工作目录之外读/写(基本上我只想允许它们从标准的输入和输出中写入和读取) 我在互联网上的不同地方读到,在创建AppDomain时,可以使用PermissionState设置这些权限,然后在其中执行可执行文件。然而,我

我问题的标题可能已经暴露了一个事实,那就是我不确定我想要什么,因为它可能没有意义

对于一个项目,我希望能够在我的应用程序中运行可执行文件,同时重定向它们的标准输入和输出,以便我的应用程序可以通过这些流与它们通信

同时,我不想让这些可执行文件执行某些操作,比如使用网络,或者在它们自己的工作目录之外读/写(基本上我只想允许它们从标准的输入和输出中写入和读取)

我在互联网上的不同地方读到,在创建AppDomain时,可以使用PermissionState设置这些权限,然后在其中执行可执行文件。然而,我并没有找到一种方法通过可执行文件的标准输入和输出与可执行文件进行通信,这是必不可少的。但是,我可以在启动新进程(
Process.Start()
)时执行此操作,尽管这样我无法设置允许可执行文件执行的操作的边界

我的直觉告诉我,我应该在AppDomain中以某种方式执行流程,这样流程就可以在域中“运行”,尽管我找不到直接执行的方法

我的一位同事通过创建一个代理应用程序实现了这一点,该应用程序基本上是另一个创建AppDomain的可执行文件,在其中执行实际的可执行文件。然后,代理应用程序由主应用程序中的进程启动。我认为这是一个很酷的想法,尽管我觉得我不需要这一步

我可以添加一些代码,其中包含我到目前为止创建流程和appdomain所做的工作,尽管问题已经很长了。如果您愿意,我会添加它。

代理应用程序听起来是一种非常合理的方法(假设您只想运行.NET程序集)

您获得了不同进程的隔离,这允许您通过stdin/stdout进行通信,并提供了额外的健壮性,使不受信任的可执行文件不会使主应用程序崩溃(如果它在主应用程序进程内的AppDomain中运行,则可能会崩溃)

然后,代理应用程序将设置受限AppDomain并执行沙盒代码,类似于此处描述的方法:

此外,您可以使用操作系统级mechansims来减少进程的攻击面。这可以通过以下方式实现:例如,以最低完整性启动代理进程,从而删除对大多数资源的写入访问(例如,仅允许在AppData\LocalLow中写入文件)。请参阅示例


当然,你需要考虑这个水平的沙箱是否足够你。Sandboxing,一般来说是很难的,孤立的水平总是在某种程度上。

这是非常复杂的,很不幸的是,这些安全性的方法一次又一次地失败,这是一个巨大的努力,没有人能把它们弄对。但是,您可以做的是以有限的用户身份运行流程-虽然它没有提供CAS提供的粒度,但它也更容易,并保持流程隔离。进程内扩展很容易杀死您的应用程序:)无法在
AppDomain
中运行流程,因为它们是完全独立的概念
AppDomain
s在进程中运行,反之亦然。当然,它们首先只适用于.NET应用程序:)@Luaan那么当我调用
AppDomain.Create(…).ExecuteAssembly(pathToMyStuff)
时会发生什么?我觉得这会启动一个新的进程,但根据您的陈述,情况并非如此……它在给定的
AppDomain
中执行给定程序集中的入口点方法(如果我简化,它相当于
GetType(“Program”).GetMethod(“Main”).Invoke();
)。没有产生新的进程
AppDomain
实际上是一种用于软件隔离进程的机制,但使用起来相当棘手,而且隔离对于真正的沙箱来说太有限了。.NET MSDN文档实际上相当不错,在
ExecuteAssembly
上,它实际上明确指出“此方法不会创建新的进程或应用程序域,也不会在新线程上执行入口点方法。”我想知道,如果我们回到“先检查文档”模型,而不是仅仅因为方法的名称是“execute”,而期望我们的假设是正确的,我们会节省多少精力“:D对我来说,最初的假设源于“它位于
AppDomain
,因此它显然无法启动进程。”-这可能是错误的。我想我不太明白AppDomain调用ExecuteAssembly()时做了什么,对我来说,它听起来像是启动了另一个进程,虽然很明显,如果我与代理应用程序通信,我实际上是在与通过创建的appdomain加载到代理应用程序中的可执行文件交谈。@Glubus:
ExecuteAssembly
不会启动新进程,而是在同一进程的appdomain中执行。因此,如果您与“代理”应用程序进行通信,那么通信是有效的。那么您是说代理应用程序中的Console.WriteLine()在AppDomain中运行时,在执行的程序集中调用它时正在写入同一个流?在阅读了您和Luaans的评论之后,我现在似乎有点明显了。@Glubus:我自己没有尝试过,但我希望是这样,因为访问stdin/stdout发生在进程(而不是AppDomain)级别,并且执行的程序集在该特定进程中运行。我现在明白了您的预期,这对我开始有意义了。从这个意义上讲,代理应用程序实际上并不是一个额外的执行层,因为我们要运行的程序实际上是作为代理应用程序的一部分加载的。我觉得我不需要再移除那个层了。非常感谢