gpt4 book ai didi

windows - Powershell 中的 FindWindow 给我 0(在 w11 22h2 FR 上): unattended character in the title of a cmd elevated console?

转载 作者:行者123 更新时间:2023-12-05 04:19:24 27 4
gpt4 key购买 nike

8 年后 this question使用 Windows 11 22H2 FR,Powershell PSVersion 5.1.22621.169命令:

FindWindow("ConsoleWindowClass", "Administrateur : X:\windows\system32\cmd.exe")

输出0

经过一些研究,我使用 SPY++ 来阅读标题和类(class)。我已经从 SpY++ 的编辑框复制/粘贴到一个 PS 字符串变量 ($title)。我注意到在这个复制/粘贴的 $title 字符串中:

[byte]$title[14]= 160

[byte]$title[14] 看起来像一个空格,就在这里,在中间“r :”字符串索引 14 用于操作系统的法语版本。

FindWindow 返回一个很好的这个字符句柄!

问题:为什么在提升的 cmd 控制台?正常吗?它在哪里记录?

我使用的代码:

$code = @'
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindow(string ClassName,string WindowName);
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError = true)]
public static extern bool ShowWindow( IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError = true)]
public static extern IntPtr SetWindowText(IntPtr HWND, string Text);
'@
Add-Type -MemberDefinition $code -Name Window -Namespace Test
# please, open an elevated console cmd
#Be carrefull, "administrateur" in french OS. So, adapt if you test...
# here, "[byte]$title[14] = 32" -> it's a space, it's not 160
$name = "Administrateur : X:\windows\system32\cmd.exe"
$classW = "ConsoleWindowClass"
[Test.Window]::FindWindow($classW, $name)
#it gives 0

我不知道如何将 160 的代码点放入 system.string(我只能从 SPY++ 复制/粘贴标题)。所以我无法给出第二次测试的正确代码。

总结:

我启动提升的 cmd 控制台并看到标题:

"Administrateur : X:\windows\system32\cmd.exe"
...............|..............................

上面一行用于定位代码点为160的“奇怪”字符的位置。

使用 PS,我尝试使用 FindWindow 来获取此窗口的句柄如果我从 SPY++ ([byte]$title[14] = 160) 复制/粘贴标题,FindWindow 就可以了。

如果我从键盘输入文本 ([byte]$title[14] = 32),FindWindow 返回 0(错误)。

获取代码点为 160 的标题文本是否正常(在 FR 字符串中的索引 14 处)?

最佳答案

码位为160(十进制)/0xA0(十六进制)的Unicode字符为:

看起来就像一个空间,但又明显不同。

要嵌入字符串,您有多种选择;最简单的方法是将 expandable (double-quoted) string ( "..." ) 与嵌入式子表达式( $(...) 或仅在 PowerShell (Core) 6+ 中,Unicode escape sequence 一起使用:

# Subexpression:
# Works in Windows PowerShell too.
"Administrateur$([char] 0xA0): X:\windows\system32\cmd.exe"

# Unicode escape sequence:
# Works in PowerShell (Core) 6+ only
"Administrateur`u{A0}: X:\windows\system32\cmd.exe"

至于为什么这个角色存在:

该字符的最初目的是防止单词之间的自动换行,这是常规空格字符无法做到的 - 请参阅维基百科关于 non-breaking space 的文章。

考虑到窗口标题总是单行,这不能单独成为使用角色的原因。

例如,以英语或德语作为系统语言时,该字符存在:管理员的(本地化)单词和 : < 之间没有字符

zett42 观察到以下关于字符出现的原因法语,例如:

  • 在法语(可能还有其他语言)中,:(和其他标点符号)前面必须有一个(不间断的)空格 - 请参见 What’s The Deal With French Spacing?

  • general 中,在 : 和它前面的单词之间使用不间断空格是有意义的,以免在新行上出现“悬空的”:

  • 可能,有共享代码: 之前插入不间断空格,用于本地化为法语的文本,因此它恰好出现在此上下文也是如此。

务实地说:

  • 关于查找按标题运行提升 session 的窗口的行为是模糊的。

  • 关于解析这样的标题(一旦找到),分成 : 之前和之后的部分实际上在所有语言中都是一样的,但前提是您仅按常规空格拆分,例如
    "Administrateur$([char] 0xA0): X:\windows\system32\cmd.exe" -split ' '(相比之下,-split "Administrateur$([char] 0xA0): X:\windows\system32\cmd.exe" 也会按不间断空格拆分)。


至于如何诊断问题以编程方式:

(Get-Process -Name cmd | Where-Object MainWindowTitle -Match '^Administr').MainWindowTitle | 
ForEach-Object ToCharArray |
ForEach-Object {
[pscustomobject] @{ Char = $_; CodePoint = '0x{0:x}' -f ([uint16] $_) }
}

上面的代码将每个字符及其 Unicode 代码点打印在自己的行上。

This answer 显示便利函数 Debug-String ,它大大简化了检查字符串中是否存在意外字符的过程。

关于windows - Powershell 中的 FindWindow 给我 0(在 w11 22h2 FR 上): unattended character in the title of a cmd elevated console?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74799746/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com