Forum Discussion

LionelG's avatar
LionelG
Copper Contributor
Nov 14, 2024

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

  • adhs1's avatar
    adhs1
    Copper 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_94's avatar
    VBA_94
    Copper 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)

     

     

     

  • LionelG's avatar
    LionelG
    Copper 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.

    • GregM's avatar
      GregM
      Copper 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.

    • NikolinoDE's avatar
      NikolinoDE
      Gold 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.

      • LionelG's avatar
        LionelG
        Copper Contributor

        Thanks for your time, have a nice day.

  • NikolinoDE's avatar
    NikolinoDE
    Gold 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.

Resources