找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 47|回复: 0

获取命令行

[复制链接]
发表于 4 天前 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 tlwh163 于 2024-12-23 15:16 编辑

最近在折腾拦截 Link.exe 玩 但是遇到一个问题 CommandLineToArgvW 会把命令行中的双引号 消除 这不好!

Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function GetCommandLineW Lib "kernel32" () As Long
Private Declare Function CommandLineToArgvW Lib "shell32" (ByVal lpCmdLine As Long, ByVal pnNumArgs As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long

Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Ptr As Long, ByVal NewVal As Long)
Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Ptr As Long, Ret As Any)
Private Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private CmdArgv() As String     '命令行列表: 用数组便于插入/删除等编辑操作
Private CmdArgc As Long         '命令行列表的有效数量(k)  (不是很有必要 先用着)

''返回命令行信息:
''Index = -1    输出 命令行参数(全部) 的空格分隔字符串(带前导空格,不包括执行文件名)
''Index = 0     输出 执行文件名       如果本身没有引号,附加首尾的引号
''Index < k     输出 命令行参数(单项)
Public Function Commandw(Optional ByVal Index As Long = -1) As String
    If CmdArgc <= 0 Then GetCommands CmdArgv(), CmdArgc
    If Index < 0 Then       '已经有命令行解析列表,取数据就好
        Dim w As Long       '数组下标0元素暂时置为"",用完再恢复
        GetMem4 VarPtr(CmdArgv(0)), w: PutMem4 VarPtr(CmdArgv(0)), 0&
        Commandw = Join(CmdArgv, " "): PutMem4 VarPtr(CmdArgv(0)), w
    ElseIf Index < CmdArgc Then
        Commandw = CmdArgv(Index)   '输出 执行文件名 或 命令行参数(单项)
    End If                          '否则返回 ""
End Function

Private Sub GetCommands(CmdArgv() As String, ByRef CmdArgc As Long)
    Dim w As Long: w = GetCommandLineW(): If w = 0 Then Exit Sub
    Dim i As Long, k As Long, m() As Integer
    k = lstrlenW(w): ReDim m(0 To k)            '复制 命令行文本 到缓存区
    MemCopy m(0), ByVal w, k * 2: m(k) = 0: w = 0
    For i = 0 To k - 1                          '预处理 保留命令行中的双引号
        Select Case m(i)
            Case 34: w = Not w:   m(i) = &HFFFF '引号 替换为 &HFFFF
            Case 32, 9: If w Then m(i) = &HFFFE '空格 替换为 &HFFFE
        End Select
    Next
    Dim Argv As Long, Argc As Long              '调用 API 解析命令行
    Argv = CommandLineToArgvW(VarPtr(m(0)), VarPtr(Argc))
    If Argv Then
        ReDim CmdArgv(0 To Argc - 1): CmdArgc = Argc
        GetMem4 Argv, w
        MemCopy m(0), ByVal w, k * 2            '复制 解析后的数据 到缓存区
        LocalFree Argv: Argv = 0                '释放 系统内存的引用
        w = 0: i = 0: k = 0
        Do
            Select Case m(i)
                Case 0                          '遇到截止符 复制 命令行数据
                    CmdArgv(k) = String(i - w, 0)
                    MemCopy ByVal StrPtr(CmdArgv(k)), m(w), LenB(CmdArgv(k))
                    k = k + 1:  w = i + 1
                Case &HFFFF: m(i) = 34          '&HFFFF 恢复为 引号
                Case &HFFFE: m(i) = 32          '&HFFFE 恢复为 空格
            End Select:         i = i + 1
        Loop Until (k = Argc)                   '计数器到了 结束扫描
        If Mid(CmdArgv(0), 1, 1) <> Chr(34) Then
            CmdArgv(0) = Chr(34) & CmdArgv(0) & Chr(34)
        End If
    End If
End Sub
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-27 20:37 , Processed in 0.029423 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表