CommandLineToArgvW (shell32)
Last changed: -64.66.107.66

.
Summary

C# Signature:

[DllImport("shell32.dll")]
static extern IntPtr CommandLineToArgvW(
   [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);

VB.NET Signature:

Declare Function CommandLineToArgv Lib "shell32.dll" Alias "CommandLineToArgvW" ( _
    ByVal lpCmdLine As String, _
    ByRef pNumArgs As Integer) As Long

User-Defined Types:

None.

Notes:

Minimum DLL Version Shell32.dll version 6.0 or later
Minimum operating systems Windows XP
Unicode This function is implemented as Unicode.

Tips & Tricks:

Please add some!

Sample Code:

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace CmdLineToArgvW
{
    class MainModule
    {
        static void Main(string[] args)
        {
            Console.WriteLine( "args.Length: {0}", args.Length );
            for ( int i = 0; i < args.Length; i++ )
            {
                Console.WriteLine( "args[{0}]={1}", i, args[i] );
            }

            Console.WriteLine();

            int argc;
            IntPtr argvPtr = IntPtr.Zero;
            try
            {
                argvPtr = CommandLineToArgvW( Environment.CommandLine, out argc );
                // CommandLineToArgvW will list the executable as argv[0].
                // I want to see the same count as you get from "string[] args".
                Console.WriteLine( "argc: {0}", argc - 1 );

                // argvPtr is a pointer to a pointer; dereference it
                IntPtr argPtr = Marshal.ReadIntPtr( argvPtr );

                for ( int i = 0; i < argc; i++ )
                {
                    string arg = Marshal.PtrToStringUni( argPtr );

                    // CommandLineToArgvW will list the executable as argv[0].
                    // I want to get the same output that "string[] args" yields,
                    // so I'll skip the output for i = 0
                    if ( i > 0 )
                    {
                        Console.WriteLine( "argv[{0}]={1}", i - 1, arg );
                    }

                    // Increment the pointer address by the number of Unicode bytes
                    // plus one Unicode character for the string's null terminator
                    int unicodeByteCount =
                        Encoding.Unicode.GetByteCount( arg ) +
                        Encoding.Unicode.GetByteCount( new char[] { Char.MinValue } );
                    argPtr = new IntPtr( argPtr.ToInt32() + unicodeByteCount );
                }

            }
            finally
            {
                GlobalFree( argvPtr );
            }

        }

        [DllImport("shell32.dll")]
        static extern IntPtr CommandLineToArgvW(
            [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine,
            out int pNumArgs);

        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalFree(IntPtr hMem);
    }
}

Alternative Managed API:

Do you know one? Please contribute it!

Documentation