如何使用VBA关闭通过Shell.Application打开的记事本?
解决VBA打开记事本后关闭的问题
你当前用Shell.Application.Open打开文件的方式,无法直接获取记事本的进程对象,所以调用fso.close或fso.quit会报错——因为fso是Shell应用程序对象,并非记事本进程实例。下面提供几种可靠的关闭方案:
方案1:通过Shell函数获取进程ID后关闭
先用Shell函数启动记事本,保存返回的进程ID,再通过Windows API终止该进程:
Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare PtrSafe Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Sub OpenAndCloseNotepad() Dim processId As Long Dim hProcess As Long Dim sfile As String sfile = "C:\Users\Universal\Desktop\test.txt" ' 启动记事本,获取进程ID processId = Shell("notepad.exe """ & sfile & """", vbNormalFocus) ' 等待几秒(可选,模拟操作时间) Application.Wait Now + TimeValue("00:00:03") ' 打开进程句柄 hProcess = OpenProcess(&H1F0FFF, 0, processId) If hProcess <> 0 Then ' 终止进程 TerminateProcess hProcess, 0 ' 关闭句柄 CloseHandle hProcess End If End Sub
方案2:通过WMI查询并关闭指定记事本进程
如果不知道进程ID,可以通过WMI查询打开目标文件的记事本进程,再终止它:
Sub CloseNotepadByFile() Dim wmiObj As Object Dim process As Object Dim sfile As String sfile = "C:\Users\Universal\Desktop\test.txt" Set wmiObj = GetObject("winmgmts:\\.\root\cimv2") ' 查询所有记事本进程,匹配命令行中的目标文件路径 For Each process In wmiObj.ExecQuery("SELECT * FROM Win32_Process WHERE Name='notepad.exe'") If InStr(process.CommandLine, Chr(34) & sfile & Chr(34)) > 0 Then process.Terminate Exit For End If Next process End Sub
方案3:通过窗口标题激活后关闭(简单但局限性大)
记事本窗口标题会包含文件名,可通过激活窗口后发送Alt+F4关闭,但如果有多个同名文件或记事本窗口,可能误关:
Sub CloseNotepadByTitle() Dim windowTitle As String Dim sfile As String sfile = "C:\Users\Universal\Desktop\test.txt" ' 提取文件名作为窗口标题的一部分(记事本标题格式:文件名 - 记事本) windowTitle = Mid(sfile, InStrRev(sfile, "\") + 1) & " - 记事本" On Error Resume Next AppActivate windowTitle If Err.Number = 0 Then SendKeys "%{F4}" ' 发送Alt+F4 End If On Error GoTo 0 End Sub
内容的提问来源于stack exchange,提问作者Krensk
相关产品推荐
相关产品推荐

