gpt4 book ai didi

shell - 函数 ExecCmd,曾经在 access 2007 中工作,但在 access 2013(64 位)中不再工作

转载 作者:行者123 更新时间:2023-12-02 00:01:51 34 4
gpt4 key购买 nike

我曾经能够在我的 access 2007 db 中使用以下函数运行运行外部程序(如 exiftool 或 image magick)的命令行。我迁移到 access 2013,经过一些代码调整后,数据库可以正常工作,但这个函数 ExecCmd 除外。当我使用它时,我没有收到任何错误,但什么也没有发生。

有人可以帮忙吗?通过向我展示错误或建议更好的方法来做同样的事情。

Public Const SEE_MASK_DOENVSUBST As Long = &H200
Public Const SEE_MASK_IDLIST As Long = &H4
Public Const SEE_MASK_NOCLOSEPROCESS As Long = &H40
Public Const SW_HIDE As Long = 0
Public Const SW_SHOW As Long = 5
Public Const WAIT_TIMEOUT As Long = 258&

Public Type SHELLEXECUTEINFOA
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type
Public Declare PtrSafe Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Public Declare PtrSafe Function GetExitCodeProcess Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpExitCode As Long) As Long
Public Declare PtrSafe Function ShellExecuteEx Lib "shell32.dll" (ByRef lpExecInfo As SHELLEXECUTEINFOA) As Long
Public Declare PtrSafe Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long



Public Function ExecCmd(ByVal vsCmdLine As String, Optional ByRef vsParameters As String, Optional ByRef vsCurrentDirectory As String = vbNullString, Optional ByVal vnShowCmd As Long = SW_SHOW, Optional ByVal vnTimeOut As Long = 200) As Long
Dim lpShellExInfo As SHELLEXECUTEINFOA
With lpShellExInfo
.cbSize = Len(lpShellExInfo)
.lpDirectory = vsCurrentDirectory
.lpVerb = "open"
.lpFile = vsCmdLine
.lpParameters = vsParameters
.nShow = vnShowCmd
.fMask = SEE_MASK_DOENVSUBST Or SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_IDLIST
End With

If ShellExecuteEx(lpShellExInfo) Then
Do While WaitForSingleObject(lpShellExInfo.hProcess, vnTimeOut) = WAIT_TIMEOUT
DoEvents
Loop

GetExitCodeProcess lpShellExInfo.hProcess, ExecCmd
CloseHandle lpShellExInfo.hProcess
Else
ExecCmd = vbError
End If
End Function

我发现了另一个类似的功能,但第一个更好,因为它能够隐藏运行命令。这有效:

Option Explicit

Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type

Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare PtrSafe Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long

Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&

Public Sub ExecCmd(cmdline As String)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ReturnValue As Integer

' Initialize the STARTUPINFO structure:
start.cb = Len(start)

' Start the shelled application:
ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)

' Wait for the shelled application to finish:
Do
ReturnValue = WaitForSingleObject(proc.hProcess, 0)
DoEvents
Loop Until ReturnValue <> 258

ReturnValue = CloseHandle(proc.hProcess)
End Sub

最佳答案

我能够使用一个简单的测试用例重现您的问题。 VBA 过程...

Sub test()
Dim r As Variant
r = ExecCmd("cscript.exe", "C:\Users\Public\Documents\foo.vbs", "", 0)
End Sub

...在 32 位 Access 2013 下工作正常,但在 64 位 Access 2013 下静默失败。但是,以下代码似乎在 64 位 Access 2013 下工作:

Sub test2()
Dim sh As Object ' WshShell
Set sh = CreateObject("WScript.Shell")
sh.Run "cscript.exe C:\Users\Public\Documents\foo.vbs", 0
Set sh = Nothing
End Sub

有关详细信息,请参阅

Run Method (Windows Script Host)

关于shell - 函数 ExecCmd,曾经在 access 2007 中工作,但在 access 2013(64 位)中不再工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20868234/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com