Sign in to follow this  
Followers 0
MISIIM

DllCall and CommandLineToArgvW return value

7 posts in this topic

How do I read the return value from CommandLineToArgvW? It is supposed to return an array.

http://msdn2.microsoft.com/en-us/library/b...391(VS.85).aspx

Func _CommandLineToArgv($cmd)
    Local $ret = DllCall("shell32.dll", "wstr", "CommandLineToArgvW", "wstr", $cmd, "int*", 0);
    If @error Then Return SetError(1, 0, 0);
    If $ret[0] = 0 Then Return SetError(2, 0, 0);
    
    Local $retarr = $ret[0];

    ; Copy data to AutoIt array.
    
    DllCall("kernel32.dll", "ptr", "LocalFree", "ptr", $retarr);
EndFunc

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You would have to do something like the following for the call:

Local $ret = DllStructCreate("int")
DllCall("shell32.dll", "wstr", "CommandLineToArgvW", "wstr", $cmd, "int", DllStructGetPtr($ret))

If you look at the syntax:

Syntax

LPWSTR *CommandLineToArgvW( LPCWSTR lpCmdLine,

int *pNumArgs

);

Parameters

lpCmdLine

[in] Pointer to a null-terminated Unicode string containing the full command line. An application will usually directly pass on the value returned by a call to the GetCommandLineW function.

If this parameter is the empty string (""), the function returns the path to the current executable file.

pNumArgs

[out] Pointer to a variable of type int that receives the number of array elements returned.

If you read the "pNumArgs" section its looking for a pointer to a variable of type int. So you will need to create a Dll Structure(DllStructCreate("int")) and then get the pointer (DllStructGetPtr($ret)). Edited by DarkMatter

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

DarkMatter

You would have to do something like the following for the call:

Well, but your answer don`t give a solution. :) I trying, but unsuccesfull :)

#include <Array.au3>

$GetCmd = DllCall("kernel32.dll", "str", "GetCommandLine")
$GetCmd = $GetCmd[0]

$Struct = DllStructCreate("int")

$ret = DllCall("shell32.dll", "wstr", "CommandLineToArgvW", "wstr", $GetCmd, "ptr", DllStructGetPtr($Struct))
    
_ArrayDisplay($ret)

MsgBox(0, "Numbers of array", DllStructGetData($Struct, 1, 1))

DllCall("kernel32.dll", "ptr", "LocalFree", "ptr", $ret[0])

Share this post


Link to post
Share on other sites

MISIIM

Easy way - it`s use: special array $CmdLine; StringSplit() function; StringRegExp() function :)

Share this post


Link to post
Share on other sites

There is nothing wrong with "int*" ever since this feature was added to AutoIt.

What is wrong, is the return type you all try to use - "wstr" (MSDN clearly says the return type is a pointer. Pointer of a pointer, in fact), and the obvious fact that AutoIt doesn't support C type string arrays right off the bat, so you can't just expect to get the result without moving a pinky :)

So something like this:

Func _CommandLineToArgv($cmd)
    Local $ret = DllCall("shell32.dll", "ptr", "CommandLineToArgvW", "wstr", $cmd, "int*", 0), $iChar, $iCount, $tPtr, $tBuffer, $aRet
    If @error Then Return SetError(1, 0, 0);
    If $ret[0] = 0 Then Return SetError(2, 0, 0);
    
    $tPtr = DllStructCreate("ptr", $ret[0])
    Local $retarr = DllStructGetData($tPtr, 1);

    ; Copy data to AutoIt array.
    $tBuffer = DllStructCreate("wchar[4095]", $retarr)
    While $iCount < $ret[2]
        $iChar += 1
        If DllStructGetData($tBuffer, 1, $iChar) = "" Then
            $iCount += 1
            If DllStructGetData($tBuffer, 1, $iChar+1) = "" Then ExitLoop
            DllStructSetData($tBuffer, 1, "|", $iChar)
        EndIf
    WEnd
    $aRet = StringSplit(DllStructGetData($tBuffer, 1), "|")
    
    DllCall("kernel32.dll", "ptr", "LocalFree", "ptr", $ret[0]);
    Return $aRet
EndFunc

Although I wonder why do you need all this in first place, when there is $CmdLine array.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Siao

Perfect! Thank you guru! :)

Share this post


Link to post
Share on other sites

Thank you. It works.

I needed this because I am writing a Commmand Prompt simulator so I need to parse the arguments that I am going to pass to another program.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0