2015-06-19 172 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

相關問題