So what is happening is my console program opens up then runs external c# program/code from a text file. This all runs fine but when I close the original form window the program/code that it executed also closes. Is there a way to prevent the text file code I was running from closing?
This is the code its calling to run the program
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);
}
where the buffer is the code/program in bytes
and this is my main
static void Main(string[] args)
{
var data = File.ReadAllText(@"program.txt");
MemExe(data);
}
The simplest method to avoid this is to start the application from Visual Studio without using debugging. You do so by selecting "Start Without Debugging" from the Debug menu or by pressing Ctrl-F5. When the program stops executing, you must press a key before the console window closes.
Before the end of your code, insert this line: system("pause"); This will keep the console until you hit a key.
Keep Console Open With the Ctrl + F5 Shortcut in C# The best approach for keeping our console window open after the execution of code is to run it with the Ctrl + F5 shortcut of the Microsoft Visual Studio IDE. Our program runs in debug mode when we run our code by clicking the start button in the Visual Studio IDE.
Run your program using <Ctrl>+<F5>. This will automatically keep the console window open until a key is pressed.
I'm not going to get into the details of whether or not you should actually do what you want. At first it seems like a bad practice. But considering you have reasons to do this...
When your process closes, whatever it's executing halts automatically. In order to prevent this behavior, you have two options:
Option 1 - Running a second process
Instead of creating one C# project, you create two. The main one uses Process.Start
to activate the second one. If the main one closes, the second one will remain executing until it finishes.
Option 2 - Disable the close button
If you don't mind to interact with native Windows code, thus preventing your code from executing in other environments which is now officially going to be supported with VS 2015, you can manually disable the close button from the CMD doing this:
[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)));
}
Reference: https://social.msdn.microsoft.com/forums/vstudio/en-us/545f1768-8038-4f7a-9177-060913d6872f/disable-close-button-in-console-application-in-c
A workaround would be to change the project's Output type
in Project's Properties -> Application -> Output type
from Console Application to Windows Application (see Screenshot)
This way no Console Window is created, so the the process will neither appear as two running processes nor can it be terminated by closing the Console Window.
This is the approach I would take. Your method is executed in a non-background-thread that prevents the process from terminating once the main-thread has terminated. However, you still cannot close the console window. That's why I would suggest switching to a 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);
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With