所以正在发生的事情是我的控制台程序打开然后从文本文件运行外部c#程序/代码。这一切都运行良好,但当我关闭原始窗体窗口时,它执行的程序/代码也关闭。有没有办法阻止我从关闭运行的文本文件代码?
这是它运行程序的代码
static void MemExe(byte[] buffer)
{
Assembly asm = Assembly.Load(buffer);
if (asm.EntryPoint == null)
throw new ApplicationException("No entry point found!");
MethodInfo ePoint = asm.EntryPoint;
ePoint.Invoke(null, null);
}
其中缓冲区是以字节为单位的代码/程序
这是我的主要
static void Main(string[] args)
{
var data = File.ReadAllText(@"program.txt");
MemExe(data);
}
答案 0 :(得分:3)
我不打算详细说明你是否应该按照自己的意愿行事。起初,这似乎是一种不好的做法。但考虑到你有理由这样做......
当您的进程关闭时,无论它正在执行什么都会自动停止。为了防止出现这种情况,您有两种选择:
选项1 - 运行第二个流程
不是创建一个C#项目,而是创建两个。主要使用Process.Start
来激活第二个。如果主要关闭,第二个将继续执行直到完成。
选项2 - 停用关闭按钮
如果您不介意与本机Windows代码交互,从而阻止您的代码在VS 2015正式支持的其他环境中执行,您可以手动禁用CMD中的关闭按钮:
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
internal const UInt32 SC_CLOSE = 0xF060;
internal const UInt32 MF_ENABLED = 0x00000000;
internal const UInt32 MF_GRAYED = 0x00000001;
internal const UInt32 MF_DISABLED = 0x00000002;
internal const uint MF_BYCOMMAND = 0x00000000;
static void Main(string[] args)
{
EnableCloseButton(this, false);
}
public static void EnableCloseButton(IWin32Window window, bool bEnabled)
{
IntPtr hSystemMenu = GetSystemMenu(window.Handle, false);
EnableMenuItem(hSystemMenu, SC_CLOSE, (uint)(MF_ENABLED | (bEnabled ? MF_ENABLED : MF_GRAYED)));
}
答案 1 :(得分:1)
解决方法是将Output type
中的项目Project's Properties -> Application -> Output type
从控制台应用程序更改为 Windows应用程序(请参阅屏幕截图)
这样就不会创建控制台窗口,因此该过程既不会显示为两个正在运行的进程,也不能通过关闭控制台窗口来终止。
这是我要采取的方法。您的方法在非后台线程中执行,该线程阻止进程在主线程终止后终止。但是,您仍然无法关闭控制台窗口。这就是我建议切换到Windows Application
using System;
using System.IO;
using System.Reflection;
using System.Threading;
namespace StackOverflow
{
public static class Program
{
static void Main(string[] args)
{
RunExternalFunctionThread t = new RunExternalFunctionThread(File.ReadAllBytes(@"program.txt"));
t.Run();
}
private class RunExternalFunctionThread
{
private Byte[] code;
public RunExternalFunctionThread(Byte[] code)
{
this.code = code;
}
public void Run()
{
Thread t = new Thread(new ThreadStart(this.RunImpl));
t.IsBackground = false;
t.Priority = ThreadPriority.Normal;
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void RunImpl()
{
Assembly asm = Assembly.Load(this.code);
if (asm.EntryPoint == null) throw new ApplicationException("No entry point found!");
MethodInfo ePoint = asm.EntryPoint;
ePoint.Invoke(null, null);
}
}
}
}