我有一个 Console 程序,它主要用来重启 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

但这段代码还是有点问题,在启动时会看到 窗口 一瞬间从显示到隐藏,这不是我想要的效果,我希望它能够实现完全隐藏,请问我该如何实现?

  • Richard

  • 如果你的 Console 不需要诸如 Console.WriteLine 这类输出流,我建议你直接在构建应用程序的时候将 程序类型 改成 Windows Application ,截图如下:

    接下来可以使用如下 C# 代码。

    static void Main ( string [] args )

    for ( int i = 0 ; i < int .MaxValue; i++)

    File.AppendAllText( "C:\\SosexUst.log" , $"i= {i} {Environment.NewLine} " );

    Thread.Sleep( 1000 );

    可以发现,log文件已经在不断的写入了。

    它的本质就是修改了 .exe 的PE头,这样应用程序启动后就不按照 Console 默认的会话走了。

  • abatishchev

  • 可以调用 win32 api 实现,参考如下代码:

    [ 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;

    可以参考 github:https://github.com/abatishchev/reg2run/blob/master/ManualConsole.cs 了解更多和 console 有关的 api 接口。

    Richard 大佬这种方案挺好的,对了,要想看 PE 头,可以用 PPEE.exe 小工具查看。

    可以看到,其实指的是 PE 头中的 SubSystem 字段。 返回搜狐,查看更多

    责任编辑:

    平台声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。