61

I'm trying to automate some tasks for myself and I wrote a few .NET Core 1.0 console applications. One of them is BrowserRouter - a simple application which, based on a URL pattern, decides which browser / browser profile to open when I click on HTTP(S) links.

That works fine, but there is always the console window which appears and immediately disappears.

Is there a way to run the .NET Core console application silently (hiding the console window)?

I know in the full .NET Framework it is possible to change the output type to Windows Application, but that's not available (yet?) for .NET Core.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
radek.pribyl
  • 631
  • 1
  • 5
  • 5
  • 5
    What about using a windows service? – VahidNaderi Aug 04 '16 at 20:22
  • 4
    Possible duplicate of [How to Run a C# console application with the console hidden](http://stackoverflow.com/questions/836427/how-to-run-a-c-sharp-console-application-with-the-console-hidden) – Matthew Thurston Aug 04 '16 at 20:26
  • 4
    @VahidNaderi .Net Core is X-Plat - not sure how a Windows Service would work on Linux/MAC. – DaveShaw Aug 04 '16 at 20:27
  • @DaveShaw you're right, then maybe we should [vote for it](https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/9515328-windows-services-in-net-core) – VahidNaderi Aug 04 '16 at 20:35
  • 7
    @mThurston No, the other question is 1. not about .net core and 2. addresses the situation when you open a console application from within windows application. So you can control it from within the windows app. – radek.pribyl Aug 05 '16 at 06:59
  • I think the question is still valid: you may want to build a .net core application (let's assume you are using VSCode rather than VS) and want to launch a windows service (on a window platform, of course). – Jaime Aug 08 '16 at 06:14
  • 4
    Look at [this answer](http://stackoverflow.com/questions/37346383/hosting-asp-net-core-as-windows-service) – Frank Aug 09 '16 at 16:04
  • This answer - http://stackoverflow.com/a/836436/453798 might help... – Geek Aug 10 '16 at 12:08
  • How do you start BrowserRouter today ? – Ralf Bönning Aug 17 '16 at 21:01

9 Answers9

42

Update 2018: In .NET Core 3.0+, you will be able to set <OutputType>WinExe</OutputType> inside of the csproj file.

Currently, this is not directly possible out of the box because Windows EXE files contain a flag indicating if it is a "console" or "GUI" application that Windows evaluates even before starting the application. However, this flag can be changed using editbin.exe (ships with Visual Studio' C++ build tools as far as I know).

Building on this, you could create a self-contained .NET Core application (removing the "type": "platform" from the project.json and adding a runtimes section) so your project output includes an actual .exe file and add a post-build script that invokes editbin.exe /subsystem:windows yourapp.exe.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • There is more documentation for the SUBSYSTEM option for editbin.exe here: https://learn.microsoft.com/en-us/cpp/build/reference/subsystem I copied editbin.exe and link.exe to a folder under my solution. In VS2017 I used the following in the post build event for my project: `"$(SolutionDir)Build\bin\editbin.exe" -SUBSYSTEM:WINDOWS "$(SolutionDir)Project1\bin\Debug\netcoreapp1.1\win10-x64\Project1.exe"` I don't know if anyone else has had this, but I couldn't get many of the macros to work (possibly because I had to tweak the csproj to get it to build as an exe). – open-collar Apr 22 '17 at 19:14
  • @martinullrich 3.0 solution worked great , any idea how I can stop this application after hiding its kestrel cmd . I want to close/stop the application using a button, or icon in windows. any hints? – Dragon May 16 '21 at 19:38
  • In combination with Blazor Server I ran into an issue where Controllers added to a Razor library did not work anymore (missing endpoint). – Alex Jan 13 '23 at 03:22
10

With .NET Core 3.0+ (including .NET 5), just do this in csproj:

<OutputType>WinExe</OutputType>

Vadim Peretokin
  • 2,221
  • 3
  • 29
  • 40
6

I really wanted to do it as Martin resolved, but I couldn't find editbin.exe. Well, I should have run the Visual Studio installer and installed Microsoft Visual C++, but I had limited memory, so I found another way of doing it NSubsys on NuGet.

The application will be made to run in hidden mode on publishing.

Note to copy the Npm install command from NuGet since searching it from package manager for solution didn't seem to find any results.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rey_coder
  • 422
  • 8
  • 12
  • Would you be able to provide instructions for how exactly you used NSubsys to get this to work? After installing the NuGet package, what other steps did you have to take? Thanks. – Ciaran Gallagher Jun 12 '19 at 12:47
  • Also, am I correct in saying that NSubsys won't be triggered on local dev? Will it only be triggered once the program has been published (as a self-contained package)? – Ciaran Gallagher Jun 12 '19 at 12:49
4

In the .NET Core SDK 2.1 (I have 2.1.500) this project file is working:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net47</TargetFramework>
    </PropertyGroup>

</Project>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alexei Shcherbakov
  • 1,125
  • 13
  • 10
3

If you, like me, want to deploy an ASP.NET Core MVC application

  • on an internal network
  • don't want IIS or WebHostService
  • don't care about Linux/Mac
  • and want to hide the Kestrel console from the user

then you should read Microsoft's official documentation on how to host an ASP.NET Core application in a Windows Service.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
QuantumHive
  • 5,613
  • 4
  • 33
  • 55
  • this works well if you're looking to host static content -- however, if you want to spawn worker processes with isolated memory space. A hack for now is to Dllimport kernel32 and call FreeConsole(), or as others have mentioned use editbin.exe in your postbuild event – Samir Banjanovic Dec 15 '18 at 07:22
  • @SamirBanjanovic calling `FreeConsole` will not hide (release) the console window because it's owned by the runtime (dotnet), not the netcore DLL. – McGuireV10 Dec 26 '18 at 13:39
  • @McGuireV10 that is true if you run the app via dotnet command. If you're running the app as standalone after publish the `freeconsole()` works – Samir Banjanovic Dec 27 '18 at 13:37
  • Fair point, I had forgotten the self-contained publish option produces an exe (too much bloat for me in SCDs at this point in time). – McGuireV10 Dec 27 '18 at 13:53
1

This is probably not the best or cleanest solution, but a trick I've used before. If you start a new Windows Forms application, then remove the reference to the form from the Program.cs file, it will run the application in the background with nothing showing up in the taskbar or on the desktop. It does appear in Task Manager though.

I used this trick to write an app to play a prank on a friend. It would run in the background and perform a system beep at random intervals. Again, probably not the most elegant solution, but one way of doing it.

Aaron Rumford
  • 556
  • 1
  • 7
  • 21
1

I tried editing the .xproj file, but it seems it is ignored by Visual Studio/.NET.

I don't think it is currently supported as .NET was developed with web sites and console applications in mind. Microsoft has recently decided they will revert back to good old MSBuild. (Changes to Project.json)

So, I think your best bet is to wait till then.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
OzieGamma
  • 426
  • 3
  • 10
1

you can hide a .net core console application on runtime as soon it starts using windows api call. see the sample code below

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace HideConsoleApp
{
    class Program
    {
        [DllImport("Kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();
        [DllImport("User32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
        static void Main(string[] args)
        {
            Console.WriteLine("press any key to hide console window");
            Console.ReadKey();
            VsConsoleWindow(0);
            Console.ReadKey();
        }

        public static void VsConsoleWindow(int i)
        {
           
            IntPtr hWnd = GetConsoleWindow();
            if (hWnd != IntPtr.Zero)
            {
                // value of cv = 0 hide console window  
                // value of cv = 1 show console window
                ShowWindow(hWnd, i);
                Thread.Sleep(5000);
                ShowWindow(hWnd, 1);
            }
            return;
        }



    }
}

https://github.com/robinsondominic/hide-net-core-console-application

iamdeed
  • 354
  • 4
  • 19
0

You're looking for the ProcessStartInfo class. Specifically the CreateNoWindow Property.

ProcessStartInfo processInfo = newProcessStartInfo("Name", "args");
processInfo.CreateNoWindow = true;

The class name and property vary a little based on the version on .NET you're using. It is also important to note that this needs to be populated and called before the process is initialized. This works when the program in question is being called programmatically or from PowerShell scripts, etc.

Hawkeye4040
  • 126
  • 10