Windows VBA7中的ShellExecuteEx打印失败,访问被拒绝
我们在Word宏中有VBA代码,用于下载一个或多个文档,然后使用Windows功能打印它们。该代码在Windows 2000、XP和7(32位和64位)上的Word版本97、2000、2003、2007和2010(32位)中成功运行 但在64位Word 2010和2013中,对ShellExecuteEx的调用失败。我们已将VBA7(64位)的声明更新为和。例如:Windows VBA7中的ShellExecuteEx打印失败,访问被拒绝,windows,vba,Windows,Vba,我们在Word宏中有VBA代码,用于下载一个或多个文档,然后使用Windows功能打印它们。该代码在Windows 2000、XP和7(32位和64位)上的Word版本97、2000、2003、2007和2010(32位)中成功运行 但在64位Word 2010和2013中,对ShellExecuteEx的调用失败。我们已将VBA7(64位)的声明更新为和。例如: #If VBA7 Then Type SHELLEXECUTEINFO cbSize As Long fMask A
#If VBA7 Then
Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As LongPtr
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As LongPtr
lpIDList As LongPtr
lpClass As String
hkeyClass As LongPtr
dwHotKey As Long
hIcon As LongPtr
hProcess As LongPtr
End Type
Declare PtrSafe Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" _
(sei As SHELLEXECUTEINFO) As Boolean
#End If
用法如下:
Dim bReturn As Boolean
Dim sei As SHELLEXECUTEINFO
With sei
.cbSize = Len(sei) ' size of the object
.fMask = SEE_MASK_NOCLOSEPROCESS ' indicate that we want a hProcess back
.hwnd = GetDesktopWindow() ' the window we are calling from
.lpVerb = "print" ' print the file
.lpFile = lpFile ' the file we want to print
.lpParameters = vbNullString ' no parameters because its a file
.lpDirectory = vbNullString ' use the current dir as working dir
.nShow = SW_HIDE ' state of the window to open
End With
bReturn = ShellExecuteEx(sei)
If bReturn Then
WaitForSingleObject sei.hProcess, 5000
CloseHandle sei.hProcess
DoEvents
Else
MsgBox "ShellExecuteEx failed with code: " & Err.LastDllError
End If
在32位Word中它可以工作,但在64位Word中,对ShellExecuteEx的调用总是失败,返回5(seu ERR\u ACCESSDENIED)。我尝试了fMask
的一系列标志值(包括SEE_MASK\u NOASYNC),尝试了不指定hwnd
的值以及nShow
的不同值,所有这些都有相同的失败结果
更简单的函数可以在32位和64位字中工作,但它太死板了。我们希望使用ShellExecuteEx
,因为它在打印多个文档时效果更好:它使我们能够在发送另一个打印请求之前等待打印应用程序(Word、Adobe Reader等)准备就绪。否则,如果应用程序未就绪,打印请求将失败。(我尝试在打印请求之间等待几秒钟,但这并不可靠。)
为什么
ShellExecute
打印文件,但是ShellExecuteEx
在拒绝访问的情况下失败?对于64版本的操作系统,您必须使用LenB而不是Len。
完整的答案如下:.cbSize=Len(sei)
因此应该被.cbSize=LenB(sei)