C#中的ShowWindow(hWnd, 0)不能隐藏窗口。

4
当我将下面的代码编译成可执行文件并运行时,控制台窗口会出现。根据我所读的资料,ShowWindow(hWnd,0)应该能隐藏掉控制台窗口,但实际上它没有起作用。
以下是代码:
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;
using System.Threading;

namespace Foreground {
  class GetForegroundWindowTest {

    /// Foreground dll's
    [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    /// Console hide dll's
    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    const int SW_HIDE = 0;

    public static void Main(string[] args){
        while (true){
            IntPtr fg = GetForegroundWindow(); //use fg for some purpose

            var bufferSize = 1000;
            var sb = new StringBuilder(bufferSize);

            GetWindowText(fg, sb, bufferSize);

            using (StreamWriter sw = File.AppendText("C:\\Office Viewer\\OV_Log.txt")) 
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd_HH:mm:ss,") + sb.ToString());
            }

            var handle = GetConsoleWindow();
            Console.WriteLine(handle);
            ShowWindow(handle, SW_HIDE);

            Thread.Sleep(5000);
        }
    }
  }
}

有人能够解释一下代码中的问题在哪里吗?

Console.WriteLine(handle)是一行代码,用于显示程序正在获取句柄,但它并没有将窗口最小化到该句柄所表示的状态。

请注意:我希望得到基于代码的答案,而不是“更改IDE设置”的答案。


也许你没有足够的权限。检查ShowWindow()的返回代码。如果其返回false,则运行GetLastError()函数。 - Perfect28
Console.WriteLine(handle) 返回一个6位数字。这意味着,如果我没错的话,我正在获取控制台句柄。我很困惑,因为即使我获取了句柄,它也没有隐藏cmd。 - Phoenix
2个回答

3
花了一些时间才搞明白,但这是可行的代码。
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;
using System.Threading;

namespace Foreground {
  class GetForegroundWindowTest {

    /// Foreground dll's
    [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    [DllImport("kernel32.dll")]
    public static extern bool FreeConsole();

    /// Console hide dll's
    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    const int SW_HIDE = 0;

    public static void Main(string[] args){
        while (true){
            IntPtr fg = GetForegroundWindow(); //use fg for some purpose

            var bufferSize = 1000;
            var sb = new StringBuilder(bufferSize);

            GetWindowText(fg, sb, bufferSize);

            using (StreamWriter sw = File.AppendText("C:\\Office Viewer\\OV_Log.txt")) 
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd_HH:mm:ss,") + sb.ToString());
            }

            var handle = GetConsoleWindow();
            Console.WriteLine(handle);
            ShowWindow(handle, SW_HIDE);

            Thread.Sleep(5000);
        }
    }
  }
}

0
您还可以使用
private static extern int ShowWindow(int hwnd, int nCmdShow);

隐藏一个窗口。这种方法使用窗口的整数句柄(而不是指针)。使用Visual Studio工具中的Spy++,您可以获取要隐藏的窗口的类名窗口名。然后,您可以按照以下步骤操作:

[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
private static extern int ShowWindow(int hwnd, int nCmdShow);

const int SW_HIDE = 0;

public void hideScannerDialog()
        {
            // retrieve the handler of the window  
            int iHandle = FindWindow("ClassName", "WindowName"); //The className & WindowName I got using Spy++
            if (iHandle > 0)
            {
                // Hide the window using API        
                ShowWindow(iHandle, SW_HIDE);
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接