Hide the console window from a console application [duplicate] - c#

This question already has answers here:
Show/Hide the console window of a C# console application
(9 answers)
Closed 7 years ago.
I have an application that was using the console, but I changed all the code to write to a file instead of the console. I would now like the console to stop appearing when I run the application. How do I do this? I do not know what is opening the console in the first place, even though nothing is being written to it in the code.
I have looked in the applications references and cannot find System.Console being referenced. I though disabling that would fix it or point me in the right direction with errors. I am not sure where else to look.
All the other things I found online talk about making the console hidden. I would like it to not appear in the first place.

Go to the Application Properties and change Output Type from Console Application to Windows Application.
Or you can do it using a code below
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
And in main
const int SW_HIDE = 0;
const int SW_SHOW = 5;
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE); // To hide
ShowWindow(handle, SW_SHOW); // To show
Also, you can run you application as a service. In order to do this you should create a service - File->New Project->Visual C#->Windows->Windows Service. Then create a public method StartWork() and add all you logic there. And call this method in OnStart().
protected override void OnStart(string[] args)
{
try
{
this.StartJobs();
}
catch (Exception ex)
{
// catching exception
}
}
public void StartWork()
{
// all the logic here
}
In main you should create this service and use System.ServiceProcess.ServiceBase.Run() to run it as service or call StartWork() to run it as console application.
static void Main(string[] args)
{
TestService = new TestService ();
#if DEBUG
TestService.StartWork()();
#else
System.ServiceProcess.ServiceBase.Run(TestService );
#endif
}

Related

C# Windows Messages in Console Application?

I need to use IPC to receive messages from another process. Currently I am using WPF application to receive messages using WindowsMessages but I am wondering if that communication would work in a ConsoleApp instead? At first glance I've noticed that HwndSource cannot be found in ConsoleApp so the question is if there is a way to receive WindowsMessages in a ConsoleApp (preferred way) or if it would be easier to create a WPF app instead?
You could use a walkaround (agree, not the nicest and cleanest way but worked for me).
Add a reference to System.Windows.Forms and create a class that derives from Form as follows:
public class ConsoleReceiver : Form
{
public ConsoleReceiver()
{
SetFormProperties();
}
private void SetFormProperties()
{
Text = "YourWindowName";
Width = 0;
Height = 0;
ShowIcon = false;
ShowInTaskbar = false;
Opacity = 0.0;
Visible = false;
ControlBox = false;
MaximizeBox = false;
MinimizeBox = false;
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
protected override void WndProc(ref Message m)
{
//Wait for your message here
Console.WriteLine($"Window message received {m.Msg} {m.LParam} {m.WParam}");
base.WndProc(ref m);
}
}
Above code will create an invisible form window which you will be able to find by name and send you window messages to.
In the Main method of your console app Create a message loop and initialize your form:
static void Main(string[] args)
{
Application.Run(new ConsoleReceiver());
}
Lastly, within your sender app find the window by name and once it is found you will be able to send your window messages.
Declare the method:
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
And use it as follows:
FindWindow(null, "YourWindowName");
The SendMessage and PostThreadMessage APIs will only work when there is an active message loop running in the receiving application.
If you want to communicate with a console app on the same machine, you could use named pipes. There is an example available in the documentation that should be helpful.

Giving focus to an external application (Chrome)

Good morning,
I'm trying to figure out how to put the focus on Google Chrome. That is to say to make as a click on the software in the taskbar (already open).
Thank you for helping me to put the focus on Google Chrome.
You can use the following function to bring chrome to front and to focus it.
The code uses 2 windows API calls because what you need is not directly provided by the .Net framework.
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class Program
{
[DllImport("user32.dll")]
[return: MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
private static extern bool ShowWindow(IntPtr hWnd, int flags);
[DllImport("user32.dll")]
public static extern int SetForegroundWindow(IntPtr hwnd);
private static bool FocusChromeWindow()
{
foreach (Process chrome in Process.GetProcessesByName("chrome"))
{
// In case the process did not reveal a main window handle
// try to restore it in case it is hidden
if (chrome.MainWindowHandle == IntPtr.Zero)
{
ShowWindow(chrome.Handle, 9); // 9 = Restore
}
// If main window handle is still zero,
// this chrome process is one of the background
// workers chrome starts. Skip it.
if (chrome.MainWindowHandle != IntPtr.Zero)
{
SetForegroundWindow(chrome.MainWindowHandle);
return true;
}
}
return false;
}
static void Main(string[] args)
{
FocusChromeWindow();
Console.ReadLine();
}
}

How to use Application.ThreadExit in non-WindowsForms Application?(Multithreaded app, need to check main thread with event) [duplicate]

This question already has answers here:
Capture console exit C#
(10 answers)
Closed 8 years ago.
My application needs to know when the main thread ends and I found Application.ThreadExit handler. However I can't figure out how to use it. All the examples show Application.ThreadExit += new EventHandler(AppEvents.OnThreadExit);. But this is for Windows Forms, My application is a Console Application.
Thank you!
In console, I always use the SetConsoleCtrlHandler delegate, with DllImport
After class declaration, use:
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
And then in program, set the handler:
var handler = new ConsoleEventDelegate(ConsoleEventCallback);
SetConsoleCtrlHandler(handler, true);
static bool ConsoleEventCallback(int eventType)
{
if (eventType == 2)
{
//Main thread Console is being closed!
// handle other threads
}
Thread.Sleep(5000);
return false;
}
You can write your code as shown below for console as well :-
Application.ThreadExit += new EventHandler(OnThreadExit);
which will subscribe the event it means whenever thread will exit it will call OnThreadExit method as shown below :-
public static void OnThreadExit(object sender, EventArgs e)
{
Console.WriteLine("thread is shutting down.");
}

When closing Console Window its close the all application

I'm working with windows form and i have a main form and when I click on some button he open a console window that do some work and when its done I want to close the console without closing the all application (main form). I try to close the console with Environment.Exit(1) or the function Destroy() that belongs to the Destroy() and Create() the console window. the Environment.Exit(1) and Destroy() both close the console but close the form too.
I wonder if there is a way to close only the console without closing the whole application
EDIT
private void btSync_Click(object sender, EventArgs e)
{
Create();
ServerSync sycs=new ServerSync();
Thread sync = new Thread(new ThreadStart(sycs.run));
sync.Start();
}
The Create() open a Console window that run a Socket() Thread.
Problem Solved
When im start the thread i add to the end of code a ThreadName.Abort and outside the thread i check if ThreadName.IsAlived==false and inside the if i Hide() the console and then Destroy() And Its Works!
the Hide() method from AppDeveloper answer.
Thanks for your help!
Instead of using Environment.Exit() hide the Console Window
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0x0;
const int SW_SHOW = 0x5;
public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
}
Maybe there is a console.hide() option? could try that out.

Activating the main form of a single instance application

In a C# Windows Forms application I want to detect if another instance of the application is already running.
If so, activate the main form of the running instance and exit this instance.
What is the best way to achieve this?
Scott Hanselman answers on you question in details.
Here is what I'm currently doing in the application's Program.cs file.
// Sets the window to be foreground
[DllImport("User32")]
private static extern int SetForegroundWindow(IntPtr hwnd);
// Activate or minimize a window
[DllImportAttribute("User32.DLL")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_RESTORE = 9;
static void Main()
{
try
{
// If another instance is already running, activate it and exit
Process currentProc = Process.GetCurrentProcess();
foreach (Process proc in Process.GetProcessesByName(currentProc.ProcessName))
{
if (proc.Id != currentProc.Id)
{
ShowWindow(proc.MainWindowHandle, SW_RESTORE);
SetForegroundWindow(proc.MainWindowHandle);
return; // Exit application
}
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
catch (Exception ex)
{
}
}
You can use such detection and activate your instance after it:
// Detect existing instances
string processName = Process.GetCurrentProcess().ProcessName;
Process[] instances = Process.GetProcessesByName(processName);
if (instances.Length > 1)
{
MessageBox.Show("Only one running instance of application is allowed");
Process.GetCurrentProcess().Kill();
return;
}
// End of detection
Aku, that is a good resource. I answered a question similar to this one a while back. You can check my answer here. Even though this was for WPF, you can use the same logic in WinForms.

Categories