Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 设置隐藏窗口的窗口状态_C#_.net_Vb.net_Pinvoke_Showwindow - Fatal编程技术网

C# 设置隐藏窗口的窗口状态

C# 设置隐藏窗口的窗口状态,c#,.net,vb.net,pinvoke,showwindow,C#,.net,Vb.net,Pinvoke,Showwindow,很久以前我问过这个问题,它在这里解决了: 但是现在,由于未知的原因,这里提供的C或Vb.Net代码不起作用,我不明白为什么不起作用 我对那里提供的原始代码做了一些修改,但是我测试了原始代码,没有工作 发生的事情是,我无法解开一个隐藏的过程,我不知道我在哪里失败了。乍一看,我认为FindWindowEx的句柄与我想要的句柄并不完全对应 以下是我的p/调用函数签名和showwindow枚举: <DllImport("user32.dll", SetLastError:=True, CharSe

很久以前我问过这个问题,它在这里解决了:

但是现在,由于未知的原因,这里提供的C或Vb.Net代码不起作用,我不明白为什么不起作用

我对那里提供的原始代码做了一些修改,但是我测试了原始代码,没有工作

发生的事情是,我无法解开一个隐藏的过程,我不知道我在哪里失败了。乍一看,我认为FindWindowEx的句柄与我想要的句柄并不完全对应

以下是我的p/调用函数签名和showwindow枚举:

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto, 
           BestFitMapping:=False, ThrowOnUnmappablechar:=True)>
Friend Shared Function FindWindow(
                 ByVal lpClassName As String,
                 ByVal lpWindowName As String
) As IntPtr
End Function

<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto, 
           BestFitMapping:=False, ThrowOnUnmappablechar:=True)>
Friend Shared Function FindWindowEx(
                 ByVal hwndParent As IntPtr,
                 ByVal hwndChildAfter As IntPtr,
                 ByVal strClassName As String,
                 ByVal strWindowName As String
) As IntPtr
End Function

<DllImport("user32.dll")>
Friend Shared Function GetWindowThreadProcessId(
                 ByVal hWnd As IntPtr,
                 ByRef processId As Integer
) As Integer
End Function

<DllImport("User32", SetLastError:=False)>
Friend Shared Function ShowWindow(
                 ByVal hwnd As IntPtr,
                 ByVal nCmdShow As ProcessUtil.WindowState
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

Public Enum WindowState As Integer
    Hide = 0
    Normal = 1
    ShowMinimized = 2
    Maximize = 3
    ShowMaximized = Maximize
    ShowNoActivate = 4
    Show = 5
    Minimize = 6
    ShowMinNoActive = 7
    ShowNA = 8
    Restore = 9
    ShowDefault = 10
    ForceMinimize = 11
End Enum

记事本的问题在于它有3个windows spy++,类名:

一,。便条簿 2.MSCTFIME用户界面 3.输入法

你得到了我得到的第二个,MSCTFIME用户界面的句柄,这就是为什么你不能显示它。您需要指定类名Notepad以获得正确的句柄:

pHandle = FindWindowEx(IntPtr.Zero, pHandle, "Notepad", Nothing)

现在是您开始使用.NETFramework源代码的时候了,这样您就可以发现这样的代码为什么不能自己工作。请访问以开始

在搜索框中键入Process.MainWindowHandle,您将到达。很容易看出是ProcessManager.GetMainWindowHandle完成了任务。单击GetMainWindowHandle。它非常小,请单击FindMainWindow。注意它是如何枚举窗口的,向右滚动一点,查看它是否枚举完成作业的WindowsCallback。点击它,很容易看到它是决定一个窗口是否是主窗口的主窗口。点击它:

    bool IsMainWindow(IntPtr handle) {

        if (NativeMethods.GetWindow(new HandleRef(this, handle), NativeMethods.GW_OWNER) != (IntPtr)0
            || !NativeMethods.IsWindowVisible(new HandleRef(this, handle)))
            return false;

        return true;
    }
换句话说,如果它是一个拥有的窗口,它就不是一个主窗口句柄。或者如果它不可见

后者当然是你的报应。您隐藏了窗口,现在框架代码不再认为它可以作为主窗口。因此Process.MainWindowHandle返回IntPtr.Zero,您的代码将无法继续工作

一个明显的解决方法是简单地重写.NET Framework代码并跳过IsWindowVisible测试。然而,这是一个重要的测试,它避免了找到几乎任何进程都会创建的消息窗口。它们用于内部管道。另一个答案提到了它们。你可以用Spy++看到它们,记事本上有两个。如果不是按照顺序创建的,那么您将首先找到主窗口。这并不能保证在任何过程中都会发生

正确的解决方法是,你不能忘记你做了一些对窗口非常不友好的事情。记事本本身从不隐藏其主窗口。你基本上把它变成了僵尸,用户再也不能做任何事情来恢复窗口了。剩下的唯一选项是使用任务管理器终止进程。因此,让它再次可见完全是你的工作。例如,对于不能忽略的作业,必须在程序退出之前恢复它们


或者干脆别这么做,这样乱动用户的窗口简直是恶意的。

你试过将WindowsState设置为正常吗?@Nemo谢谢你的评论。是的,我尝试了枚举的每个值,但它没有还原隐藏的窗口。在While循环结束后,我将FindWindowEx的结果句柄与提供CMDOW命令行应用程序的句柄进行了比较,结果有所不同,CMDOW提供了主HWND,但与以前的代码相同,我不明白为什么现在会发生这种情况。@ElektroStudios你有没有尝试使用Process.getProcessesByName记事本和Process.MainWindowHandle?@ElektroStudios我刚刚在C中找到一篇有同样问题的文章。你可以自己把它做成VB@谢谢你的评论。当窗口隐藏时,Process.MainWindowHandle变为0。我无法使用win32 FindWindow函数,因为它将导致意外和低效的结果,例如当同一进程的多个实例正在运行时,当我尝试使用FindWindowEx函数时,我需要使用一些健壮的方法,如唯一标识符句柄/hwnd/pid。我知道注释juts来表示感谢并不常见,但是像这样的答案值得非常感谢,感谢您花费大量时间编写本文并链接引用。谢谢您的回答。我将分享我收到的两个答案的要点,因为@Hans Passant的答案非常具有说明性,而你的简历是一份非常好的解析简历。很难决定,两者都是受欢迎的解决方案。
pHandle = FindWindowEx(IntPtr.Zero, pHandle, "Notepad", Nothing)
    bool IsMainWindow(IntPtr handle) {

        if (NativeMethods.GetWindow(new HandleRef(this, handle), NativeMethods.GW_OWNER) != (IntPtr)0
            || !NativeMethods.IsWindowVisible(new HandleRef(this, handle)))
            return false;

        return true;
    }