Forum Discussion
KB5002653 issue with the Kernel Function GetCommandLineW
Hello,
Just to warn about this specific issue, since the installation of the KB5002653 , From an Excel 2016 VBA the function GetCommandLineW give a truncated/different result.
Sample Code:
Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineW" () As Long
Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (MyDest As Any, MySource As Any, ByVal MySize As Long)
Function ReadCmdLine() As String
Dim pCmdLine As Long ' Pointer to the string
Dim Buffer() As Byte
Dim StrLen As Long
' Get the pointer to the command line string
pCmdLine = GetCommandLine
StrLen = lstrlenW(pCmdLine) * 2
If StrLen Then
ReDim Buffer(0 To (StrLen - 1)) As Byte
CopyMemory Buffer(0), ByVal pCmdLine, StrLen
ReadCmdLine = Buffer
End If
End Function
Before the KB I had : "C:\PROGRA~2\MICROS~2\Office16\EXCEL.EXE excelfile.xlsm /parameter"
After the KB I have : ""C:\PROGRA~2\MICROS~2\Office16\EXCEL.EXE" excelfile.xlsm"
7 Replies
- adhs1Copper Contributor
Interrupting in this thread with a comments not based on VBA.
We have had the same issue as described in this thread and have implemented the standard functionality with GetCommandLine. We are running Excel 2016 32-bit.
GetCommandLine was broken by a Windows/Office update. The string it returned was simply cut off and incomplete causing the program to fail with an error. I cannot find KB5002653 in the Update History on the server any longer, so maybe it has included in a more recent update. I don't know.
Nevertheless, what worked for us in two instances now was to unistall Excel 2016 32-bit from the server and reinstall it again.
Somehow this restores the way GetCommandLine works, even with the Windows/Office updates, and the solution is now running again. How and why, I do not know however.
- VBA_94Copper Contributor
LionelG,
This bug still exists, so I think I have a rough workaround.
In the main routine, there is an If block for Excel 2016, then there is a workaround function that gets the length of the command line and adds enough length to it to read the longest switches. After that the missing quote is added where it was truncated.
Workaround function:
'TODO: Trim extra length, rather than relying on CommandLineToArgvW Private Function GetOffice2016CommandLine(ByVal pointer_vba As LongPtr) As String Const BytesPerCharacter As Long = 2& Const ExtendCommandLineCharacters As Long = 16& 'Extend by maximum switch length only - could cause rare crashes Dim bBuffer() As Byte Dim lTruncatedStringLength As Long Dim lStringLength As Long Dim lBufferLength As Long Dim tString As String If pointer_vba <> 0& Then lTruncatedStringLength = lstrlen(pointer_vba) lStringLength = lTruncatedStringLength + ExtendCommandLineCharacters If lStringLength > 0& Then lBufferLength = lStringLength * BytesPerCharacter ReDim bBuffer(0& To (lBufferLength - 1&)) As Byte APICommandLine.CopyMemory bBuffer(0&), ByVal pointer_vba, lBufferLength tString = bBuffer 'add missing final quote Mid$(tString, lTruncatedStringLength + 1&, 1&) = Chr(34) 'quote GetOffice2016CommandLine = tString End If End If End Function
In main function:
'get a pointer to the current process' command line lCommandLinePointer = APICommandLine.GetCommandLine() If Val(Application.Version) = 16# Then If Val(Application.Build) >= 5474# Then 'KB5002653 If Val(Application.Build) < 10000# Then '?Patched in Office 365, 2019, 2021, 2024 etc. tCommandLine = APICommandLine.PointerToString(lCommandLinePointer) 'a switch is not found If InStr(1&, tCommandLine, " /", vbBinaryCompare) = 0& Then 'get an extended copy of the truncated command line tCommandLine = APICommandLine.GetOffice2016CommandLine(lCommandLinePointer) 'get a pointer to the Unicode command line string copy lCommandLinePointer = StrPtr(tCommandLine) End If End If End If End If 'get a pointer to the command line arguments lCommandLineArgumentsPointer = APICommandLine.CommandLineToArgv(lCommandLinePointer, lCommandLineArgumentsCount)
- LionelGCopper Contributor
Thanks NikolinoDE
Nice try 😉, the extra quotes was not the big deal.The big problem is the missing part "/parameter"
I don't think there is a workaround for that, except uninstall the KB.It's more to inform potential unlucky users working on the old excel 2016 like me, I hope M$ plans a "Patch for the patch" 😅.
There is other known issue with this KB.- GregMCopper Contributor
Hello, do you have any news about this issue ?
On my computer, the KB5002653 has been uninstalled and the KB4484305 (patch of the patch), installed. But parameters are still ignored by getCommandLineW. I guess Microsoft patched the Excel add-ins issue related to this KB, but not ours.
I figured that writing the command line like this was solving the issue for one simple parameter :
"excel.exe /e /parameter /r macro.xlsm"
But in my case, I have 2 parameters that are paths with spaces, and GetCommandLineW stops parsing at the last space in parameters. I tried many many ways to surround parameters with quotes but nothing works.
My command line that used to work until the KB :
"excel.exe" /R "macro.xlsm" /e/%param1%;%param2%
If anyone has a solution/information, I'm all ears :) Thank you.
- NikolinoDEGold Contributor
Thank you for clarifying the nature of the main problem: the missing command line arguments, such as /parameter, and not just the handling of quotes. The problem seems to be deeper and probably rooted in how Windows or Excel interpret command line input after KB5002653.
A patch provided by Microsoft to fix or reverse this behavior would be the optimal solution. Until then, unfortunately, I have not offered any other solution suggestion or workaround.
Unfortunately, as you noted, the only effective solution so far may be to uninstall KB5002653 if possible, especially if you are using an older version of Excel (such as Excel 2016). This is not ideal for long-term stability or security, so it should be approached with caution.
Hope that maybe someone here in the forum knows another workaround or solution and can help you out.
I wish you all the best in your endeavors.
- LionelGCopper Contributor
Thanks for your time, have a nice day.
- NikolinoDEGold Contributor
The issue you are experiencing with the GetCommandLineW function being affected by the installation of KB5002653 indicates a change in how command-line arguments are being parsed or returned by Windows after this update. This can cause the result of the function to be truncated or formatted differently, impacting VBA macros that rely on this function for processing command-line arguments.
Potential Solutions
Modify VBA Code.
Example of modification:
Function CleanCmdLine(cmdLine As String) As String ' Remove leading and trailing quotes if present If Left(cmdLine, 1) = """" And Right(cmdLine, 1) = """" Then cmdLine = Mid(cmdLine, 2, Len(cmdLine) - 2) End If CleanCmdLine = cmdLine End Function
Consider using different APIs or approaches that might be less affected by the update. For instance, using Command$ in VBA directly may yield different results:
Sub GetCommandUsingVBA() MsgBox "Command line parameters: " & Command$ End Sub
Here is an attempt at a customized version of your code that handles the potential problems with extra quotes or format changes in the command line string returned by GetCommandLineW.
Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineW" () As Long Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (MyDest As Any, MySource As Any, ByVal MySize As Long) Function ReadCmdLine() As String Dim pCmdLine As Long ' Pointer to the string Dim Buffer() As Byte Dim StrLen As Long Dim RawCmdLine As String ' Get the pointer to the command line string pCmdLine = GetCommandLine StrLen = lstrlenW(pCmdLine) * 2 If StrLen Then ReDim Buffer(0 To (StrLen - 1)) As Byte CopyMemory Buffer(0), ByVal pCmdLine, StrLen RawCmdLine = Buffer End If ' Clean up potential extra quotes and formatting issues RawCmdLine = CleanCmdLine(RawCmdLine) ReadCmdLine = RawCmdLine End Function Function CleanCmdLine(cmdLine As String) As String ' Remove leading and trailing quotes if present If Left(cmdLine, 1) = """" And Right(cmdLine, 1) = """" Then cmdLine = Mid(cmdLine, 2, Len(cmdLine) - 2) End If ' Further trim or adjust as necessary to handle known formatting issues cmdLine = Replace(cmdLine, """", "") ' Remove internal quotes if needed CleanCmdLine = cmdLine End Function
The text and steps were edited with the help of AI.
My answers are voluntary and without guarantee!
Hope this will help you.
Was the answer useful? Mark as best response and Like it!
This will help all forum participants.