vba - 如何在 AutoExec 宏中获取 WinWord.exe 的命令行参数?
问题描述
在AutoExec
Word 的宏中,我想处理一些功能。为此,我需要一个 ID,它在启动 WinWord.exe 时由命令行参数给出。
例子:
"C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE" /MyParam:5
我需要这个5
我怎样才能得到这个?
解决方案
VBA 本身不提供此类信息。有必要利用 Windows API 来获取命令行参数。
下面的代码演示了如何使用GetCommandLineA
和lstrcpynA
API 来提取获取完整的命令行。然后对其进行解析以获取每个单独的参数。
Declare Function GetCommandLineA Lib "kernel32" () As Long
Declare Function lstrcpynA Lib "kernel32" ( _
ByVal pDestination As String, ByVal pSource As Long, _
ByVal iMaxLength As Integer) As Long
Function GetCmdLineInfo() As String
' Pointer to the command line
' Which will be passed as pSource to lstrcpynA
Dim ptrCmdLine As Long
' Will hold the command line after the call to lstrcpynA
' Pointer to the destination; before being passed...
' must first be initialized with enough characters to hold that string
Dim strCmdLine As String
' Get the pointer to the command line string
ptrCmdLine = GetCommandLineA
' Fill the string with enough zeros to make sure there are enough
' characters available for the command string (which will replace the content).
' 300 is an arbitrary number, more might be necessary.
strCmdLine = String$(300, vbNullChar)
' Copy from the pointer to a VBA-style string
lstrcpynA strCmdLine, pCmdLine, Len(strCmdLine)
' Remove the extra vbNullChar characters at the end of the command line
strCmdLine = left(strCmdLine, InStr(1, strCmdLine, _
vbNullChar) - 1)
GetCmdLineInfo = strCmdLine
End Function
Function GetCmdLineArgs(strCmdLine As String) As String
Dim lExePos As Long, lSpaceAfterExe As Long
Dim strArgString As String
'Get the end of the path to the exe file...
lExePos = InStr(LCase(strCmdLine), ".exe")
strArgString = Mid(strCmdLine, lExePos + 4)
'Move beyond any quote characters and spaces after '.exe'
'The first argument may be the path to a file or
'an argument beginning with a forward slash, so get it all.
lSpaceAfterExe = InStr(strArgString, " ")
If lSpaceAfterExe > 0 Then
strArgString = Mid(strArgString, lSpaceAfterExe + 1)
Else
strArgString = "No args"
End If
GetCmdLineArgs = Trim(strArgString)
End Function
Sub TestCmdLineargs()
Dim strCmdLine As String
Dim strCmdArgs
strCmdLine = GetCmdLineInfo
strCmdArgs = GetCmdLineArgs(strCmdLine)
'Debug.Print Len(strCmdLine), strCmdLine, strCmdArgs
'Extract the individual args to an array
Dim strArgChar As String
Dim lFirstArgPos As Long, lNextArgPos As Long
Dim argsList() As String
Dim strArgString As String
Dim argsCounter As Long
strArgChar = " /"
argsCounter = 0
lFirstArgPos = InStr(strCmdArgs, strArgChar)
'If the first argument is a file path, store that in the array
If left(strCmdArgs, 1) <> "/" Then
ReDim Preserve argsList(argsCounter)
strArgString = Trim(left(strCmdArgs, lFirstArgPos - 2))
argsList(argsCounter) = strArgString
argsCounter = argsCounter + 1
End If
'Get the rest of the args, that start with a /
Do While lFirstArgPos > 0
ReDim Preserve argsList(argsCounter)
strArgString = Mid(strCmdArgs, lFirstArgPos + 1)
lNextArgPos = InStr(lFirstArgPos + 2, strCmdArgs, strArgChar)
'If lNextArgPos is not greater than 0, then there are no more args
If lNextArgPos <= 0 Then
argsList(argsCounter) = strArgString
Exit Do
Else
strArgString = Mid(strCmdArgs, lFirstArgPos + 1, lNextArgPos - lFirstArgPos)
argsList(argsCounter) = strArgString
argsCounter = argsCounter + 1
lFirstArgPos = lNextArgPos
End If
Loop
Dim i As Long
For i = LBound(argsList) To UBound(argsList)
Debug.Print argsList(i)
Next
End Sub
推荐阅读
- postgresql - 如何找出 PostgreSQL 执行了哪些操作(查询)
- angular - 从 Angular observable 中移除 null 或 undefined
- numpy - PySpark-numpy 互操作性
- phpstorm - 在 PhpStorm 中复制和粘贴字符串(希伯来语)是错误的
- javascript - 将选项作为对象数组的多项选择
- assembly - 如何在c中的内联汇编中划分两个32位数字
- php-7 - 调用未定义函数 Dompdf\mb_internal_encoding()
- r - R 内核不适用于 Jupyter 笔记本
- oracle - 使用 oracle 在子查询中排序
- javascript - Mongo 同时从 2 个集合中获得价值