ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 1198|回复: 11

[求助] vba关闭pdfFactory pro,页数多时程序未完全执行完毕。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-8-9 09:29 | 显示全部楼层 |阅读模式
本帖最后由 ndt3 于 2022-8-22 14:18 编辑

各位老师:
工作流程原因需要vba控制pdfFactory pro的关闭。
现在能找到pdfFactory pro的句柄及关闭pdfFactory pro。但页数较多时pdfFactory pro未完全执行完成就会被关闭。
盖火思路想通过pdfFactory pro的标题来检查是否完成任务,完成后再关闭。
pdfFactory pro在执行中如果未完全执行完毕标题会有 “**%完成” 显示,(完成后pdfFactory pro无前述字样)但始终无法通过句柄获取正确的标题数据。

请教各位老师,烦劳各位老师能帮忙看看。十分感谢!
目前测试集中方法都失败,无法实现虚拟打印机执行完成后关闭pdfFactory pro程序。代码如下,求助哪位老师帮忙看看!十分感谢!


Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
'发送消息使用
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long


Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

#If Win64 Then
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
#Else
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
#End If
'拿到进程的运行状态并传递给第二个参数。第一个参数为处理器
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long '方案2


Const PROCESS_QUERY_INFORMATION = &H400 '十进制是1024'方案2

Const STILL_ALIVE = &H103  '十进制529 表明进程仍然存活'方案2



Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711
Const VK_Ctrl = &H11
Const VK_S = &H53
Const KEYEVENTF_KEYUP = &H2 'A
Const WM_KEYDOWN = &H100
Const WM_CLOSE = &H10
Const WAIT_TIMEOUT = &H102
Dim Excelhandle As Long
'------------以上为定义----------------

Sub smgb2() '关闭程序,不能实现pdfFactory pro正常运行结束后关闭程序!
Dim datStartTime As Date

'通过列出系统全部进程,进行匹配
Set msoft = GetObject("winmgmts:").execquery("select * from win32_process where name like '%.exe'")

    For Each s In msoft       '用s.name可以列出所有运行的exe文件
      If s.Name = "fppdis4.exe" Then
     pid = s.processid
        ' s.Terminate'直接退出
         'Exit Sub
      End If
    Next
   
   
   
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
'Dim hProcess As Long
'hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid) '打开进程
If hProcess Then ReadProcessMemory hProcess, ByVal &H12F82C, base, 4, 0& '读写进程内存
CloseHandle hProcess '关闭进程句柄
CloseHandle pid
AppActivate pid, 0
PostMessage hProcess, WM_CLOSE, 0, 0 '直接发送窗口信息也是不能关闭
PostMessage pid, WM_CLOSE, 0, 0
'Application.Quit'直接退出excel了

If hProcess <> 0 Then
        datStartTime = Now
        Do
          If WaitForSingleObject(hProcess, 250) <> WAIT_TIMEOUT Then
            Exit Do
          End If
          DoEvents
          If max_wait_seconds > 0 Then
            If DateDiff("s", datStartTime, Now) > max_wait_seconds Then Exit Do
          End If
        Loop
CloseHandle hProcess '两种方式都试试
CloseHandle pid
    End If
  MsgBox "RUN END."

   
       'Shell "taskkill /im SerialScan.exe" '这个是直接杀进程,也可以关闭
      
End Sub





Sub smgb() '关闭程序,这个也是直接关
'通过列出系统全部进程,进行匹配
Set msoft = GetObject("winmgmts:").execquery("select * from win32_process where name like '%.exe'")

    For Each s In msoft       '用s.name可以列出所有运行的exe文件
      If s.Name = "fppdis4.exe" Then
     pid = s.processid
        ' s.Terminate'直接退出
         'Exit Sub
      End If
    Next
   
   
   
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
  isDone = False
  Do '一直卡在这里,状态码一直为259 ,实际未完全运行结束状态码还是259,这里实际有问题!!!!无法在pdfFactory pro正常运行结束后关闭程序!
  '通过处理器拿到进程状态码
  Call GetExitCodeProcess(hProcess, ExitCode)
  Debug.Print ExitCode
  DoEvents
  '如果状态码一直是运行中(259),则一直循环
  Loop While ExitCode = STILL_ALIVE
  
  
  

CloseHandle hProcess '两种方式都试试
CloseHandle pid
  's.Terminate
  MsgBox "RUN END."

   
      
      
End Sub



TA的精华主题

TA的得分主题

发表于 2022-8-9 12:17 | 显示全部楼层
考虑一下异步运行操作应用程序,会等待程序结束后再执行后一段代码。

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-9 13:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
chixun9999 发表于 2022-8-9 12:17
考虑一下异步运行操作应用程序,会等待程序结束后再执行后一段代码。

这个真心不知道怎么弄了。

TA的精华主题

TA的得分主题

发表于 2022-8-9 16:46 | 显示全部楼层
在vb中的使用
编辑
播报
1.VB声明
Declare Function OpenProcessLib "kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
说明
打开一个现有进程的句柄
2.返回值
Long,如执行成功,返回进程句柄;零表示失败。会设置GetLastError
3.参数表
参数 类型 及 说明
dwDesiredAccess Long,指定这个句柄要求的访问方法。指定API32.TXT文件中以PROCESS_???开头的一个或多个常数
bInheritHandle Long,如句柄能够由子进程继承,则为TRUE
dwProcessId Long,要打开那个进程的进程标识符
4.注解
这个函数经常用来打开一个要进行同步的进程(同步:即步调协同,你说完,我再说,按说好的先后次序来)
5.举例
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const PROCESS_ALL_ACCESS = &H1F0FFF=2035711
Dim hProcess As Long
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, pid) '打开进程
If hProcess Then ReadProcessMemory hProcess, ByVal &H12F82C, base, 4, 0& '读写进程内存
CloseHandle hProcess '关闭进程句柄
End If

TA的精华主题

TA的得分主题

发表于 2022-8-9 16:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
是要用同步方式调用打印进程,结束后再运行后续代码。

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-12 12:38 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
chixun9999 发表于 2022-8-9 16:47
是要用同步方式调用打印进程,结束后再运行后续代码。

谢谢,周末回去试试看!

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-15 08:28 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 ndt3 于 2022-8-15 09:14 编辑
chixun9999 发表于 2022-8-9 16:46
在vb中的使用
编辑
播报

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
'发送消息使用
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long



Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long'方案2

Const PROCESS_QUERY_INFORMATION = &H400 '十进制是1024'方案2

Const STILL_ALIVE = &H103  '十进制529 表明进程仍然存活'方案2


Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711
Const VK_Ctrl = &H11
Const VK_S = &H53
Const KEYEVENTF_KEYUP = &H2 'A
Const WM_KEYDOWN = &H100
Const WM_CLOSE = &H10
Dim Excelhandle As Long
'------------以上为定义----------------

Sub fsgb() '发送关闭命令
Dim Caption As String * 256
'Dim FT_hwnd As Long


FT_hwnd = FindWindow(vbNullString, "" & "pdfFactory pro")
FT_hwnd2 = FindWindowEx(FT_hwnd, 0, vbNullString, "页)")

If FT_hwnd = 0 Then Exit Sub: Set FT_hwnd = Nothing

  If FT_hwnd Then
  ReadProcessMemory FT_hwnd, ByVal &H12F82C, base, 4, 0& '读写进程内存
CloseHandle FT_hwnd '关闭进程句柄
'ss2 = PostMessage(FT_hwnd, WM_CLOSE, 0&, 0&) '直接发送关闭命令,存在未执行未必直接关闭问题
End If

Set FT_hwnd = Nothing
Set ss2 = Nothing
End Sub


Sub wocao()'第二种方案,也不行
  '运行脚本并获取进程ID,第二个参数决定CMD窗口如何显示,此处为最小化。
  pid = FindWindow(vbNullString, "" & "pdfFactory pro")
  '得到对进程进行操作的能力
  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
  isDone = False
  Do
  '通过处理器拿到进程状态码
  Call GetExitCodeProcess(hProcess, ExitCode)
  Debug.Print ExitCode
  DoEvents
  '如果状态码一直是运行中(529),则一直循环
  Loop While ExitCode = STILL_ALIVE
  
  
  
'-----------------END-------------------
'关闭处理器(类似于JAVA的释放对象内存)
  Call CloseHandle(hProcess)
  
  MsgBox "RUN END."


End Sub
老师,测试无法关闭。帮忙看看什么原因。谢谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2022-8-15 15:11 | 显示全部楼层
chixun9999 发表于 2022-8-9 16:46
在vb中的使用
编辑
播报

老师,测试后无法实现关闭代码如下:麻烦您帮忙看看,十分感谢!
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
'发送消息使用
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long


'拿到进程的运行状态并传递给第二个参数。第一个参数为处理器
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long '方案2


Const PROCESS_QUERY_INFORMATION = &H400 '十进制是1024'方案2

Const STILL_ALIVE = &H103  '十进制529 表明进程仍然存活'方案2



Const PROCESS_ALL_ACCESS = &H1F0FFF = 2035711
Const VK_Ctrl = &H11
Const VK_S = &H53
Const KEYEVENTF_KEYUP = &H2 'A
Const WM_KEYDOWN = &H100
Const WM_CLOSE = &H10
Dim Excelhandle As Long

Sub fsgb2() '发送关闭命令   '方案1
Dim Caption As String * 256
'Dim FT_hwnd As Long


FT_hwnd = FindWindow(vbNullString, "" & "pdfFactory pro")
FT_hwnd2 = FindWindowEx(FT_hwnd, 0, vbNullString, "页)")
FT_hwnd = OpenProcess(PROCESS_ALL_ACCESS, False, FT_hwnd) '打开进程
If FT_hwnd = 0 Then Exit Sub: Set FT_hwnd = Nothing
s = String(255, 0)
a = GetWindowText(FT_hwnd, Caption, 255)
GetWindowText FT_hwnd, Caption, Len(Caption)
'Output = "标题是:" & Caption
'ff = GetWindowText(FT_hwnd, 0, 256)
           '  'strBuff = String(GetWindowTextLength(FT_hwnd) + 1, Chr$(0))
                'GetWindowText FT_hwnd, strBuff, Len(strBuff)
               ' Sheets("续页").Range("AP1") = Caption
                'ss2 = PostMessage(FT_hwnd, WM_CLOSE, 0&, 0&) '发送关闭命令
  If FT_hwnd Then
  ReadProcessMemory PROCESS_ALL_ACCESS, ByVal &H12F82C, base, 4, 0& '读写进程内存
CloseHandle FT_hwnd '关闭进程句柄
End If

Set FT_hwnd = Nothing
Set ss2 = Nothing
End Sub

Sub gbfa2()  '行脚本并获取进程ID,第二个参数决定CMD窗口如何显示,此处为最小化。'方案2
  pid = FindWindow(vbNullString, "" & "pdfFactory pro")
  '得到对进程进行操作的能力
  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
  isDone = False
  Do
  '通过处理器拿到进程状态码
  Call GetExitCodeProcess(hProcess, ExitCode)
  Debug.Print ExitCode
  DoEvents
  '如果状态码一直是运行中(529),则一直循环
  Loop While ExitCode = STILL_ALIVE
  
  
  
'-----------------END-------------------
'关闭处理器(类似于JAVA的释放对象内存)
  Call CloseHandle(hProcess)
  
  MsgBox "RUN END."


End Sub

TA的精华主题

TA的得分主题

发表于 2023-2-13 12:03 | 显示全部楼层
解决了吗?有个问题想问问,如果没有打印任务你直接用excel vba是否能关闭另一个程序?因为如果pdfFactory pro这个程序或者窗口本身独占任务时,可能是不能由vba另外控制关闭吧?

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-3-21 13:09 | 显示全部楼层
chixun9999 发表于 2023-2-13 12:03
解决了吗?有个问题想问问,如果没有打印任务你直接用excel vba是否能关闭另一个程序?因为如果pdfFactory  ...

没解决,换了思路来实现关闭了。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-16 08:24 , Processed in 0.037937 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表