16

我无法解决这个问题。我收到一个错误:

The name 'hWnd' does not exist in the current context

这听起来很简单,可能是......抱歉问了这么明显的问题。

这是我的代码:

public static IntPtr WinGetHandle(string wName)
{
    foreach (Process pList in Process.GetProcesses())
    {
        if (pList.MainWindowTitle.Contains(wName))
        {
            IntPtr hWnd = pList.MainWindowHandle;
        }
    }
    return hWnd;
}

我尝试了许多不同的方法,但都失败了。提前致谢。

4

7 回答 7

19

更新:有关更优雅的方法,请参阅Richard 的答案。

不要忘记你是hWnd在循环内声明你——这意味着它只在循环内可见。如果窗口标题不存在怎么办?如果你想用 a 来做,for你应该在循环外声明它,将它设置在循环内,然后返回它......

IntPtr hWnd = IntPtr.Zero;
foreach (Process pList in Process.GetProcesses())
{
    if (pList.MainWindowTitle.Contains(wName))
    {
        hWnd = pList.MainWindowHandle;
    }
}
return hWnd; //Should contain the handle but may be zero if the title doesn't match

或者以更 LINQ-y 的方式....

IntPtr? handle = Process
    .GetProcesses()
    .SingleOrDefault(x => x.MainWindowTitle.Contains(wName))
    ?.Handle;
return handle.HasValue ? handle.Value : IntPtr.Zero
于 2012-11-25T02:10:08.847 回答
6

作为解决此问题的一个选项:

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

public IntPtr GetHandleWindow(string title)
{
    return FindWindow(null, title);
} 
于 2019-02-07T14:54:31.390 回答
5

迟到了几年,但正如其他人所提到的,范围hWnd只是在foreach循环中。

但是值得注意的是,假设您对该功能没有做任何其他事情,那么其他人提供的答案存在两个问题:

  1. 该变量hWnd实际上是不必要的,因为它仅用于一件事(作为 的变量return
  2. foreach循环效率低下,因为即使您找到了匹配项,您仍会继续搜索其余进程。实际上,它会返回找到匹配的最后一个进程。

假设您不想匹配最后一个进程(第 2 点),那么这是一个更清洁、更高效的函数:

public static IntPtr WinGetHandle(string wName)
{
    foreach (Process pList in Process.GetProcesses())
        if (pList.MainWindowTitle.Contains(wName))
            return pList.MainWindowHandle;

    return IntPtr.Zero;
}
于 2017-08-08T10:58:58.830 回答
4

因为您hWnd在 if 块内声明,所以它外部的 return 语句无法访问它。有关说明,请参见http://www.blackwasp.co.uk/CSharpVariableScopes.aspx

您提供的代码可以通过移动 hWnd 变量的声明来修复:

public static IntPtr GetWindowHandleByTitle(string wName)
{
    IntPtr hWnd = IntPtr.Zero;
    foreach (Process pList in Process.GetProcesses())
    {
        if (pList.MainWindowTitle.Contains(wName))
        {
            hWnd = pList.MainWindowHandle;
        }
    }
    return hWnd;
}
于 2012-11-25T02:13:12.333 回答
1

hWndforeach循环中声明。它的上下文在foeach循环内。foreach要获得它的值,请在循环外声明它。

像这样使用它,

public static IntPtr WinGetHandle(string wName){
    IntPtr hWnd = NULL;

    foreach (Process pList in Process.GetProcesses())
        if (pList.MainWindowTitle.Contains(wName))
            hWnd = pList.MainWindowHandle;

    return hWnd;
}
于 2012-11-25T02:10:06.647 回答
0
#include <windows.h>
#using <System.dll>

using namespace System;
using namespace System::Diagnostics;
using namespace System::ComponentModel;

// get window handle from part of window title
public static IntPtr WinGetHandle(string wName)
{
    IntPtr hwnd = IntPtr.Zero;
    foreach (Process pList in Process.GetProcesses())
    {
        if (pList.MainWindowTitle.Contains(wName))
        {
            hWnd = pList.MainWindowHandle;
            return hWnd;
        }
    }
    return hWnd;
}

// get window handle from exact window title
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

public IntPtr GetHandleWindow(string title)
{
    return FindWindow(null, title);
} 
于 2019-11-10T09:22:29.667 回答
0

对于允许您按窗口标题的一部分进行搜索的方法,不区分大小写(将搜索所有窗口,而不仅仅是每个进程的第一个窗口)

using System.Runtime.InteropServices;
using System.Text;

var hwnd = GetHandleByTitle("Chrome");
Console.WriteLine(hwnd);

[DllImport("USER32.DLL")]
static extern IntPtr GetShellWindow();

[DllImport("USER32.DLL")]
static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

static IntPtr GetHandleByTitle(string windowTitle)
{
    const int nChars = 256;

    IntPtr shellWindow = GetShellWindow();
    IntPtr found = IntPtr.Zero;

    EnumWindows(
        delegate (IntPtr hWnd, int lParam)
        {
                    //ignore shell window
                    if (hWnd == shellWindow) return true;

                    //get Window Title
                    StringBuilder Buff = new StringBuilder(nChars);

            if (GetWindowText(hWnd, Buff, nChars) > 0)
            {
                        //Case insensitive match
                        if (Buff.ToString().Contains(windowTitle, StringComparison.InvariantCultureIgnoreCase))
                {
                    found = hWnd;
                    return true;
                }
            }
            return true;

        }, 0
    );

    return found;
}

delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
于 2022-02-20T11:47:22.157 回答