使用C#&;移动屏幕键盘(osk.exe);全路径名

使用C#&;移动屏幕键盘(osk.exe);全路径名,c#,windows,winapi,keyboard,on-screen-keyboard,C#,Windows,Winapi,Keyboard,On Screen Keyboard,我制作了这个小.ps1脚本,因为它允许我在不使用编译器的情况下(至少直接)运行C。我想移动用cmd/c osk.exe打开的“屏幕键盘辅助功能”,因为我不能真正使用TabTip——Win8+上的平移触摸屏键盘 由于屏幕上的键盘并不像平移键盘那样漂亮,我想将键盘移动到所需的位置并调整大小。我注意到OSK有一个子窗口(OSKMainClass→ DirectUIHWND),所以我甚至去了,但运气不好。另一方面,同一代码用于单个窗口,适用于记事本,并正确放置和调整其大小 我将Process.Start

我制作了这个小
.ps1
脚本,因为它允许我在不使用编译器的情况下(至少直接)运行C。我想移动用
cmd/c osk.exe
打开的“屏幕键盘辅助功能”,因为我不能真正使用
TabTip
——Win8+上的平移触摸屏键盘

由于屏幕上的键盘并不像平移键盘那样漂亮,我想将键盘移动到所需的位置并调整大小。我注意到OSK有一个子窗口(
OSKMainClass
DirectUIHWND
),所以我甚至去了,但运气不好。另一方面,同一代码用于单个窗口,适用于记事本,并正确放置和调整其大小

我将
Process.Start()
放入if,这样它会返回一些反馈,因此我看到它找到了子窗口-这很好但是,它没有移动它

当我按下
Alt+Tab
并按住
Alt
时,一件有趣的事情出现了——OSK窗口看起来像一个灰色的全屏窗口(metro风格)。我不确定这是否是父窗口的预期行为

另外,我还以为这会是窗口样式的东西,但不,样式几乎相同(除了两个不相关的样式),所以我不知道如何继续。有什么想法吗

代码:

$CSsource = @"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Win {
    public static class API {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
        );

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(
            IntPtr parentHwnd,
            IntPtr childAfter,
            string className,
            string windowTitle
        );

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

        [DllImport("user32.dll")]
        static extern bool MoveWindow(
            IntPtr hWnd,
            int X, int Y,
            int Width, int Height,
            bool Repaint
        );

        public static void Move(
            string wClass, string wName,
            string childClass,
            int top, int left,
            int width, int height
        ) {
            IntPtr hwnd = FindWindow(wClass, wName);
            if ((int) hwnd > 0) {
                IntPtr subHwnd;
                if (childClass != String.Empty) {
                    subHwnd = FindWindowEx(hwnd, IntPtr.Zero, childClass, null);
                } else {
                    subHwnd = IntPtr.Zero;
                }

                if ((int) subHwnd > 0) {
                    MoveWindow(subHwnd, left, top, width, height + 50, true);
                    Process.Start("cmd"); //feedback from loop, heh
                } else {
                    MoveWindow(hwnd, left, top, width, height + 50, true);
                }
            }
        }
    }
}
"@

add-type -TypeDefinition $CSsource
#[Win.API]::Move('OSKMainClass', 'On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
#[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', '', 50, 50, 200, 100)
[Win.API]::Move('Notepad', 'Untitled - Notepad', '', 50, 50, 200, 100)
OSK窗口样式:

$CSsource = @"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Win {
    public static class API {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
        );

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(
            IntPtr parentHwnd,
            IntPtr childAfter,
            string className,
            string windowTitle
        );

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

        [DllImport("user32.dll")]
        static extern bool MoveWindow(
            IntPtr hWnd,
            int X, int Y,
            int Width, int Height,
            bool Repaint
        );

        public static void Move(
            string wClass, string wName,
            string childClass,
            int top, int left,
            int width, int height
        ) {
            IntPtr hwnd = FindWindow(wClass, wName);
            if ((int) hwnd > 0) {
                IntPtr subHwnd;
                if (childClass != String.Empty) {
                    subHwnd = FindWindowEx(hwnd, IntPtr.Zero, childClass, null);
                } else {
                    subHwnd = IntPtr.Zero;
                }

                if ((int) subHwnd > 0) {
                    MoveWindow(subHwnd, left, top, width, height + 50, true);
                    Process.Start("cmd"); //feedback from loop, heh
                } else {
                    MoveWindow(hwnd, left, top, width, height + 50, true);
                }
            }
        }
    }
}
"@

add-type -TypeDefinition $CSsource
#[Win.API]::Move('OSKMainClass', 'On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
#[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', '', 50, 50, 200, 100)
[Win.API]::Move('Notepad', 'Untitled - Notepad', '', 50, 50, 200, 100)
  • 标题
  • 可见的
  • WS_CLIPSIBLINGS
  • WS_儿童
  • WS\u系统菜单
  • 粗框
  • 重叠的
  • WS_最小电子邮箱
  • 左上角
  • WS_EX_ltr阅读
  • 最上面的
  • WS_EX_WINDOWEDGE
  • WS_EX_应用程序窗口
  • WS_EX_分层
  • WS_EX_NOACTIVATE
记事本窗口样式:

$CSsource = @"
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Win {
    public static class API {
        [DllImport("user32.dll")]
        static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
        );

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(
            IntPtr parentHwnd,
            IntPtr childAfter,
            string className,
            string windowTitle
        );

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

        [DllImport("user32.dll")]
        static extern bool MoveWindow(
            IntPtr hWnd,
            int X, int Y,
            int Width, int Height,
            bool Repaint
        );

        public static void Move(
            string wClass, string wName,
            string childClass,
            int top, int left,
            int width, int height
        ) {
            IntPtr hwnd = FindWindow(wClass, wName);
            if ((int) hwnd > 0) {
                IntPtr subHwnd;
                if (childClass != String.Empty) {
                    subHwnd = FindWindowEx(hwnd, IntPtr.Zero, childClass, null);
                } else {
                    subHwnd = IntPtr.Zero;
                }

                if ((int) subHwnd > 0) {
                    MoveWindow(subHwnd, left, top, width, height + 50, true);
                    Process.Start("cmd"); //feedback from loop, heh
                } else {
                    MoveWindow(hwnd, left, top, width, height + 50, true);
                }
            }
        }
    }
}
"@

add-type -TypeDefinition $CSsource
#[Win.API]::Move('OSKMainClass', 'On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
#[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', 'DirectUIHWND', 50, 50, 200, 100)
[Win.API]::Move('OSKMainClass', 'Accessibility On-Screen Keyboard', '', 50, 50, 200, 100)
[Win.API]::Move('Notepad', 'Untitled - Notepad', '', 50, 50, 200, 100)
在上面+

  • 右滚动条
  • WS_文件
OSK在其清单中有
UIAccess=“true”
,因此它以更高的完整性级别(略高于中等级别)运行

要与it交互,您需要:

  • 运行你的应用程序
  • 在清单中输入UIAccess=“true”
  • 对.exe进行签名(表示您可以在测试期间自行签名)
  • 将.exe放在Program Files文件夹中的某个位置

  • 您还可以尝试禁用UAC,以验证您缺少UIAccess是问题所在。

    是的,这很可能是我缺少的东西。你试过运行脚本吗?我真的不确定我是否可以编写并签署它,因为我打算从powershell运行。