2015-06-19 194 views
5

所以发生的是我的控制台程序打开,然后从文本文件运行外部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

你为什么不简单地创建一个新的过程? https://msdn.microsoft.com/en-us/library/system.diagnostics.process.start(v=vs.110).aspx – Benj

+0

@Benj我不能做它作为它从一个文本文件的运行代码,而不是.exe程序本身 – jLynx

+0

然后代码托管在执行过程中。一旦进程终止,就没有框架来托管/运行代码...为什么你需要终止主机进程? – Benj

回答

1

一种解决方法是改变项目”小号Output typeProject's Properties -> Application -> Output type控制台应用程序Windows应用程序(见截图)

How to Change from Console Application to Windows Application

这样没有创建控制台窗口,所以过程中既不会出现两个正在运行的进程也不能通过关闭控制台窗口终止。


这是我会采取的方法。您的方法在非后台线程中执行,以防止进程在主线程终止后终止。但是,您仍然无法关闭控制台窗口。这就是为什么我建议切换到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); 
      } 
     } 
    } 
} 
+0

我认为这个想法是正确的这个答案,但仍然,当我关闭控制台窗口它从txt文件执行的程序也关闭 – jLynx

3

我不会涉及你是否应该实际做你想做的事情的细节。起初,这似乎是一个不好的做法。但考虑到你有这样做的理由......

当你的进程关闭时,无论它正在执行自动停止。为了防止这种情况,你有两个选择:

选项1 - 运行的第二过程

而不是创建一个C#项目,您将创建两个。主要使用Process.Start激活第二个。如果主关闭,第二个将继续执行,直到完成。

选项2 - 禁用关闭按钮

如果你不介意与原生Windows代码交互,从而防止你的代码中,现已正式去其他环境中执行与2015年VS支持,您可以手动禁用从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))); 
     } 

参考:https://social.msdn.microsoft.com/forums/vstudio/en-us/545f1768-8038-4f7a-9177-060913d6872f/disable-close-button-in-console-application-in-c

+0

我希望能够在程序运行后关闭控制台窗口。但由于我运行的程序不是一个exe,我不能使用'Process.Start',因为没有什么可以开始的。这就是为什么即时通讯使用我的MemExe函数并将代码字节传递给它。至于你的选择2我希望能够关闭该控制台窗口,以便不一定能够工作 – jLynx

+1

@ DarkN3ss我想他说的是你的主控制台应用程序,然后有一个单独的服务应用程序。使用'Process.Start'从控制台应用程序启动服务应用程序,然后在启动服务应用程序时运行代码文件。因此,当您的控制台应用程序结束时,代码文件不会结束,因为它的框架就是服务应用程序。 –

+0

@MarkBalhoff你能否提供一个例子,我发现很难明确你的意思? – jLynx

相关问题