Ответ 1
Если вам не нужна консоль (например, для Console.WriteLine
), измените параметры сборки приложений как приложение Windows.
Это изменяет флаг в заголовке .exe
, поэтому Windows не выделяет сеанс консоли при запуске приложения.
Вопрос: У меня есть консольная программа, которая не должна быть видна. (Сбрасывает IIS и удаляет временные файлы.)
Прямо сейчас я могу скрыть окно сразу после запуска следующим образом:
static void Main(string[] args)
{
var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
Console.WriteLine(currentProcess.MainWindowTitle);
IntPtr hWnd = currentProcess.MainWindowHandle;//FindWindow(null, "Your console windows caption"); //put your console window caption here
if (hWnd != IntPtr.Zero)
{
//Hide the window
ShowWindow(hWnd, 0); // 0 = SW_HIDE
}
Проблема заключается в том, что на экране отображается мгновенное мгновение. Есть ли какой-либо конструктор для консольной программы, где я могу скрыть окно до его отображения?
И второе:
Я использую
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
и мне не нравится 32 в нем. Есть ли способ сделать это без DllImport?
Способ .NET:
Если вам не нужна консоль (например, для Console.WriteLine
), измените параметры сборки приложений как приложение Windows.
Это изменяет флаг в заголовке .exe
, поэтому Windows не выделяет сеанс консоли при запуске приложения.
Если я понимаю ваш вопрос, просто создайте консольный процесс вручную и скройте окно консоли:
Process process = new Process();
process.StartInfo.FileName = "Bogus.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
Я делаю это для WPF-приложения, которое запускает консольное приложение (в фоновом работнике) и перенаправляет стандартный вывод, чтобы вы могли отображать результат в окне, если это необходимо. Работая с удовольствием, дайте мне знать, если вам нужно увидеть больше кода (рабочий код, перенаправление, передача аргументов и т.д.).
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
// see the comment below
private enum StdHandle
{
StdIn = -10,
StdOut = -11,
StdErr = -12
};
void HideConsole()
{
var ptr = GetStdHandle((int)StdHandle.StdOut);
if (!CloseHandle(ptr))
throw new Win32Exception();
ptr = IntPtr.Zero;
if (!FreeConsole())
throw new Win32Exception();
}
Подробнее о вызовах API, связанных с консолью здесь
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("kernel32")]
public static extern IntPtr GetConsoleWindow();
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
static void Main(string[] args)
{
IntPtr hConsole = GetConsoleWindow();
if (IntPtr.Zero != hConsole)
{
ShowWindow(hConsole, 0);
}
}
Это должно делать то, что вы просите.