C# 尝试查看“我的程序”中打开的活动窗口时收到问号

C# 尝试查看“我的程序”中打开的活动窗口时收到问号,c#,winforms,C#,Winforms,我制作了一个软件,可以抓取重量,然后扔进光标所在的打开窗口。一切都很顺利-我只有一个问题 打开Word时收到一个问号(?)。然后软件挂起,无法正确识别窗口 当我打开Word时,我看到Word?-123.例如docx。即使我去掉了问号,软件仍然在这种情况下卡住了 我的代码: [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] s

我制作了一个软件,可以抓取重量,然后扔进光标所在的打开窗口。一切都很顺利-我只有一个问题 打开Word时收到一个问号(?)。然后软件挂起,无法正确识别窗口

当我打开Word时,我看到Word?-123.例如docx。即使我去掉了问号,软件仍然在这种情况下卡住了

我的代码:

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

    private string GetActiveWindowTitle()
    {
        const int nChars = 256;
        StringBuilder Buff = new StringBuilder(nChars);
        IntPtr handle = GetForegroundWindow();
        if (GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
        return null;
    }

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

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    public void Start(string NAME)
    {
        MSG = lblMSG.Text.Trim();
        IntPtr zero = IntPtr.Zero;
        for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++) 
        {
            Thread.Sleep(500);
            zero = FindWindow(null, NAME);
        }
        if (zero != IntPtr.Zero)
        {
           .
           .
           .
        }
    }
[DllImport(“user32.dll”)]
静态外部IntPtr GetForegroundWindow();
[DllImport(“user32.dll”)]
静态外部int GetWindowText(IntPtr hWnd、StringBuilder文本、int计数);
私有字符串GetActiveWindowTitle()
{
常数int nChars=256;
StringBuilder Buff=新的StringBuilder(nChars);
IntPtr handle=getForeGroundIndow();
如果(GetWindowText(句柄、Buff、nChars)>0)
{
返回Buff.ToString();
}
返回null;
}
[DllImport(“user32.dll”)]
私有静态外部IntPtr FindWindow(字符串lpClassName,字符串lpWindowName);
[DllImport(“user32.dll”)]
私有静态外部bool setforegroundindow(IntPtr hWnd);
公共无效开始(字符串名称)
{
MSG=lblMSG.Text.Trim();
IntPtr zero=IntPtr.zero;
对于(inti=0;(i<60)和&(zero==IntPtr.zero);i++)
{
睡眠(500);
零=FindWindow(空,名称);
}
如果(零!=IntPtr.zero)
{
.
.
.
}
}
有什么问题?如何修复它


谢谢

默认情况下,字符串和
StringBuilder
s在Windows上被编组为Unicode,所以这不是问题。但是,您正在调用ANSI版本的
GetWindowText
方法(与
FindWindow
方法相同)-这根本不起作用。Windows尝试将它能做的一切从unicode转换为ANSI,但它不能处理当前ANSI代码页之外的字符

您需要使用
CharSet.Auto

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
这将在unicode系统上使用unicode版本的
GetWindowText
GetWindowTextW
),在非unicode系统上使用ANSI版本

相比之下,如果没有CharSet.Auto,我的Word会生成

??? ?? عربي ,عربى‎‎ [Compatibility Mode] - Microsoft Word
有了它

ščř řč عربي ,عربى‎‎ [Compatibility Mode] - Microsoft Word

我的系统区域设置当前设置为阿拉伯语,因此阿拉伯语即使与ANSI
GetWindowText
一起也可以正常工作-如果我改回捷克语,ANSI中的
ŧřč
也可以正常工作,而阿拉伯语字母将被问号取代。由于英语ANSI代码页中既不支持捷克字母,也不支持阿拉伯语字母,因此更改为英语将用问号替换所有这些字母。

您的pinvoke声明引用了20世纪80年代。必须插入CharSet=CharSet.Auto,以便正确处理Unicode字符串并避免产生的转换错误?