You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Osk.exe无法正常终止,仍在后台运行的技术问题

解决Osk.exe进程无法通过Kill()彻底终止的问题

问题根源

直接调用Process.Kill()强制终止Osk.exe时,会触发系统级进程保护逻辑——作为Windows内置的屏幕输入工具,Osk存在特殊的生命周期管理,强制杀进程可能导致系统后台残留子进程或触发自动重启;而手动关闭是通过正常窗口消息退出,不会触发这类问题。另外你硬编码的WinSxS路径会随系统更新变化,可能导致启动的不是预期的Osk进程,进一步加重终止失败的问题。

解决方案

  1. 优化Osk启动逻辑:避免硬编码路径,根据系统位数和当前进程位数处理文件系统重定向,启动正确版本的Osk。
  2. 优先正常退出:先模拟手动关闭的行为发送窗口关闭消息,仅在正常退出失败时再强制终止。

修改后的代码

启动代码(含路径处理)

Imports System.IO
Imports System.Runtime.InteropServices

Public Class YourFormName
    Private ProcessusClavier As Process

    Public Sub ClavierCommandExecute()
        Dim oskPath As String
        Dim wow64State As Integer = 0

        If Environment.Is64BitOperatingSystem AndAlso Not Environment.Is64BitProcess Then
            ' 32位程序在64位系统中访问System32会被重定向到SysWOW64,需临时关闭重定向
            NativeMethods.Wow64DisableWow64FsRedirection(wow64State)
        End If

        ' 构建正确的Osk路径
        oskPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "osk.exe")

        If Environment.Is64BitOperatingSystem AndAlso Not Environment.Is64BitProcess Then
            ' 恢复文件系统重定向
            NativeMethods.Wow64RevertWow64FsRedirection(wow64State)
        End If

        Me.ProcessusClavier = Process.Start(oskPath)
    End Sub

    ' 声明系统API用于处理文件系统重定向
    Private Class NativeMethods
        <DllImport("kernel32.dll", SetLastError:=True)>
        Public Shared Function Wow64DisableWow64FsRedirection(ByRef OldValue As Integer) As Boolean
        End Function

        <DllImport("kernel32.dll", SetLastError:=True)>
        Public Shared Function Wow64RevertWow64FsRedirection(ByRef OldValue As Integer) As Boolean
        End Function
    End Class

关闭代码(优先正常退出)

Public Sub FermerCommandExecute()
        ' 先处理当前启动的Osk进程
        If Me.ProcessusClavier IsNot Nothing AndAlso Not Me.ProcessusClavier.HasExited Then
            ' 发送关闭窗口请求,模拟手动关闭
            If Me.ProcessusClavier.CloseMainWindow() Then
                ' 等待3秒让进程正常退出
                Me.ProcessusClavier.WaitForExit(3000)
            End If

            ' 若仍未退出,再强制终止
            If Not Me.ProcessusClavier.HasExited Then
                Me.ProcessusClavier.Kill()
                Me.ProcessusClavier.WaitForExit()
            End If

            Me.ProcessusClavier.Dispose()
            Me.ProcessusClavier = Nothing
        End If

        ' 兜底检查所有残留的Osk进程
        For Each proc In Process.GetProcessesByName("osk")
            If proc.CloseMainWindow() Then
                proc.WaitForExit(3000)
            End If
            If Not proc.HasExited Then
                proc.Kill()
                proc.WaitForExit()
            End If
            proc.Dispose()
        Next

        Me.Close()
    End Sub
End Class

关键说明

  • 文件系统重定向处理:32位程序在64位系统中直接访问C:\Windows\System32会被系统重定向到C:\Windows\SysWOW64,导致启动的是32位版本的Osk,关闭重定向才能启动正确的64位Osk。
  • CloseMainWindow()的作用:该方法向进程的主窗口发送WM_CLOSE消息,和手动点击关闭按钮的逻辑完全一致,能让Osk正常释放资源并退出,避免系统触发进程保护。
  • WaitForExit()超时设置:给进程预留足够的正常退出时间,避免过早执行强制终止。

内容的提问来源于stack exchange,提问作者Magellus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:21:49