Win32 API 日本語リファレンス
ホームUI.Shell › CommandLineToArgvW

CommandLineToArgvW

関数
コマンドライン文字列を引数配列に分割する。
DLLSHELL32.dll呼出規約winapiSetLastErrorあり対応OSWindows 2000 以降

シグネチャ

// SHELL32.dll
#include <windows.h>

LPWSTR* CommandLineToArgvW(
    LPCWSTR lpCmdLine,
    INT* pNumArgs
);

パラメーター

名前方向説明
lpCmdLineLPCWSTRin完全なコマンドラインを含む null 終端の Unicode 文字列へのポインター。このパラメーターが空文字列の場合、関数は現在の実行可能ファイルへのパスを返します。
pNumArgsINT*out返される配列要素の数を受け取る int へのポインター。argc に相当します。

戻り値の型: LPWSTR*

公式ドキュメント

Unicode のコマンドライン文字列を解析し、標準 C ランタイムの argv および argc の値と同様の方法で、コマンドライン引数へのポインターの配列と、その引数の個数を返します。

戻り値

型: LPWSTR*

argv に相当する、LPWSTR 値の配列へのポインター。

関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには、GetLastError を呼び出します。

解説(Remarks)

CommandLineToArgvW が返すアドレスは、LPWSTR 値の配列の先頭要素のアドレスです。この配列内のポインターの数は pNumArgs によって示されます。null 終端の Unicode 文字列への各ポインターは、コマンドライン上で見つかった個々の引数を表します。

CommandLineToArgvW は、引数文字列へのポインターと引数文字列自体のために連続したメモリブロックを割り当てます。呼び出し側のアプリケーションは、引数リストが不要になったら、それが使用しているメモリを解放する必要があります。メモリを解放するには、LocalFree 関数を 1 回呼び出します。

argvargc の引数の規則の詳細については、Argument Definitions および Parsing C Command-Line Arguments を参照してください。

lpCmdLine パラメーターとして使用するのに適したコマンドライン文字列を取得するには、GetCommandLineW 関数を使用できます。

この関数は、プログラム名を含むコマンドラインを受け付けます。プログラム名は引用符で囲んでも囲まなくてもかまいません。

CommandLineToArgvW は、バックスラッシュ文字の後に引用符文字 (") が続く場合に、それらを特別に解釈します。この解釈では、直前の引数が有効なファイルシステムのパスであることを前提としており、そうでない場合は予測できない動作をする可能性があります。

この特別な解釈は、パーサーが追跡する「引用符内」モードを制御します。このモードがオフの場合、空白は現在の引数を終了させます。オンの場合、空白は他のすべての文字と同様に引数に追加されます。

重要

CommandLineToArgvW は、引用符の外側の空白を引数の区切り文字として扱います。ただし、lpCmdLine が任意の量の空白で始まる場合、CommandLineToArgvW は最初の引数を空文字列とみなします。lpCmdLine の末尾の余分な空白は無視されます。

次の例は、Unicode のコマンドライン文字列を解析する方法を示しています。このコードは、終了時に引数リストのメモリを解放します。

#include <windows.h>
#include <stdio.h>
#include <shellapi.h>

int __cdecl main()
{
   LPWSTR *szArglist;
   int nArgs;
   int i;

   szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
   if( NULL == szArglist )
   {
      wprintf(L"CommandLineToArgvW failed\n");
      return 0;
   }
   else for( i=0; i<nArgs; i++) printf("%d: %ws\n", i, szArglist[i]);

// Free memory allocated for CommandLineToArgvW arguments.

   LocalFree(szArglist);

   return(1);
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// SHELL32.dll
#include <windows.h>

LPWSTR* CommandLineToArgvW(
    LPCWSTR lpCmdLine,
    INT* pNumArgs
);
[DllImport("SHELL32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr CommandLineToArgvW(
    [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine,   // LPCWSTR
    out int pNumArgs   // INT* out
);
<DllImport("SHELL32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function CommandLineToArgvW(
    <MarshalAs(UnmanagedType.LPWStr)> lpCmdLine As String,   ' LPCWSTR
    <Out> ByRef pNumArgs As Integer   ' INT* out
) As IntPtr
End Function
' lpCmdLine : LPCWSTR
' pNumArgs : INT* out
Declare PtrSafe Function CommandLineToArgvW Lib "shell32" ( _
    ByVal lpCmdLine As LongPtr, _
    ByRef pNumArgs As Long) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
CommandLineToArgvW.restype = wintypes.LPWSTR
CommandLineToArgvW.argtypes = [
    wintypes.LPCWSTR,  # lpCmdLine : LPCWSTR
    ctypes.POINTER(ctypes.c_int),  # pNumArgs : INT* out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('SHELL32.dll')
CommandLineToArgvW = Fiddle::Function.new(
  lib['CommandLineToArgvW'],
  [
    Fiddle::TYPE_VOIDP,  # lpCmdLine : LPCWSTR
    Fiddle::TYPE_VOIDP,  # pNumArgs : INT* out
  ],
  Fiddle::TYPE_VOIDP)
#[link(name = "shell32")]
extern "system" {
    fn CommandLineToArgvW(
        lpCmdLine: *const u16,  // LPCWSTR
        pNumArgs: *mut i32  // INT* out
    ) -> *mut *mut u16;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("SHELL32.dll", SetLastError = true)]
public static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);
"@
$api = Add-Type -MemberDefinition $sig -Name 'SHELL32_CommandLineToArgvW' -Namespace Win32 -PassThru
# $api::CommandLineToArgvW(lpCmdLine, pNumArgs)
#uselib "SHELL32.dll"
#func global CommandLineToArgvW "CommandLineToArgvW" sptr, sptr
; CommandLineToArgvW lpCmdLine, varptr(pNumArgs)   ; 戻り値は stat
; lpCmdLine : LPCWSTR -> "sptr"
; pNumArgs : INT* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "SHELL32.dll"
#cfunc global CommandLineToArgvW "CommandLineToArgvW" wstr, var
; res = CommandLineToArgvW(lpCmdLine, pNumArgs)
; lpCmdLine : LPCWSTR -> "wstr"
; pNumArgs : INT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, INT* pNumArgs)
#uselib "SHELL32.dll"
#cfunc global CommandLineToArgvW "CommandLineToArgvW" wstr, var
; res = CommandLineToArgvW(lpCmdLine, pNumArgs)
; lpCmdLine : LPCWSTR -> "wstr"
; pNumArgs : INT* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	shell32 = windows.NewLazySystemDLL("SHELL32.dll")
	procCommandLineToArgvW = shell32.NewProc("CommandLineToArgvW")
)

// lpCmdLine (LPCWSTR), pNumArgs (INT* out)
r1, _, err := procCommandLineToArgvW.Call(
	uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpCmdLine))),
	uintptr(pNumArgs),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // LPWSTR*
function CommandLineToArgvW(
  lpCmdLine: PWideChar;   // LPCWSTR
  pNumArgs: Pointer   // INT* out
): PWideChar; stdcall;
  external 'SHELL32.dll' name 'CommandLineToArgvW';
result := DllCall("SHELL32\CommandLineToArgvW"
    , "WStr", lpCmdLine   ; LPCWSTR
    , "Ptr", pNumArgs   ; INT* out
    , "Ptr")   ; return: LPWSTR*
●CommandLineToArgvW(lpCmdLine, pNumArgs) = DLL("SHELL32.dll", "void* CommandLineToArgvW(char*, void*)")
# 呼び出し: CommandLineToArgvW(lpCmdLine, pNumArgs)
# lpCmdLine : LPCWSTR -> "char*"
# pNumArgs : INT* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "shell32" fn CommandLineToArgvW(
    lpCmdLine: [*c]const u16, // LPCWSTR
    pNumArgs: [*c]i32 // INT* out
) callconv(std.os.windows.WINAPI) [*c][*c]u16;
proc CommandLineToArgvW(
    lpCmdLine: WideCString,  # LPCWSTR
    pNumArgs: ptr int32  # INT* out
): ptr WideCString {.importc: "CommandLineToArgvW", stdcall, dynlib: "SHELL32.dll".}
pragma(lib, "shell32");
extern(Windows)
wchar** CommandLineToArgvW(
    const(wchar)* lpCmdLine,   // LPCWSTR
    int* pNumArgs   // INT* out
);
ccall((:CommandLineToArgvW, "SHELL32.dll"), stdcall, Ptr{Ptr{UInt16}},
      (Cwstring, Ptr{Int32}),
      lpCmdLine, pNumArgs)
# lpCmdLine : LPCWSTR -> Cwstring
# pNumArgs : INT* out -> Ptr{Int32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uint16_t** CommandLineToArgvW(
    const uint16_t* lpCmdLine,
    int32_t* pNumArgs);
]]
local shell32 = ffi.load("shell32")
-- shell32.CommandLineToArgvW(lpCmdLine, pNumArgs)
-- lpCmdLine : LPCWSTR
-- pNumArgs : INT* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('SHELL32.dll');
const CommandLineToArgvW = lib.func('__stdcall', 'CommandLineToArgvW', 'void *', ['str16', 'int32_t *']);
// CommandLineToArgvW(lpCmdLine, pNumArgs)
// lpCmdLine : LPCWSTR -> 'str16'
// pNumArgs : INT* out -> 'int32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("SHELL32.dll", {
  CommandLineToArgvW: { parameters: ["buffer", "pointer"], result: "pointer" },
});
// lib.symbols.CommandLineToArgvW(lpCmdLine, pNumArgs)
// lpCmdLine : LPCWSTR -> "buffer"
// pNumArgs : INT* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint16_t** CommandLineToArgvW(
    const uint16_t* lpCmdLine,
    int32_t* pNumArgs);
C, "SHELL32.dll");
// $ffi->CommandLineToArgvW(lpCmdLine, pNumArgs);
// lpCmdLine : LPCWSTR
// pNumArgs : INT* out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Shell32 extends StdCallLibrary {
    Shell32 INSTANCE = Native.load("shell32", Shell32.class);
    Pointer CommandLineToArgvW(
        WString lpCmdLine,   // LPCWSTR
        IntByReference pNumArgs   // INT* out
    );
}
@[Link("shell32")]
lib LibSHELL32
  fun CommandLineToArgvW = CommandLineToArgvW(
    lpCmdLine : UInt16*,   # LPCWSTR
    pNumArgs : Int32*   # INT* out
  ) : UInt16**
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef CommandLineToArgvWNative = Pointer<Pointer<Utf16>> Function(Pointer<Utf16>, Pointer<Int32>);
typedef CommandLineToArgvWDart = Pointer<Pointer<Utf16>> Function(Pointer<Utf16>, Pointer<Int32>);
final CommandLineToArgvW = DynamicLibrary.open('SHELL32.dll')
    .lookupFunction<CommandLineToArgvWNative, CommandLineToArgvWDart>('CommandLineToArgvW');
// lpCmdLine : LPCWSTR -> Pointer<Utf16>
// pNumArgs : INT* out -> Pointer<Int32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function CommandLineToArgvW(
  lpCmdLine: PWideChar;   // LPCWSTR
  pNumArgs: Pointer   // INT* out
): PWideChar; stdcall;
  external 'SHELL32.dll' name 'CommandLineToArgvW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "CommandLineToArgvW"
  c_CommandLineToArgvW :: CWString -> Ptr Int32 -> IO (Ptr CWString)
-- lpCmdLine : LPCWSTR -> CWString
-- pNumArgs : INT* out -> Ptr Int32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let commandlinetoargvw =
  foreign "CommandLineToArgvW"
    ((ptr uint16_t) @-> (ptr int32_t) @-> returning (ptr (ptr uint16_t)))
(* lpCmdLine : LPCWSTR -> (ptr uint16_t) *)
(* pNumArgs : INT* out -> (ptr int32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library shell32 (t "SHELL32.dll"))
(cffi:use-foreign-library shell32)

(cffi:defcfun ("CommandLineToArgvW" command-line-to-argv-w :convention :stdcall) :pointer
  (lp-cmd-line (:string :encoding :utf-16le))   ; LPCWSTR
  (p-num-args :pointer))   ; INT* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $CommandLineToArgvW = Win32::API::More->new('SHELL32',
    'LPWSTR CommandLineToArgvW(LPCWSTR lpCmdLine, LPVOID pNumArgs)');
# my $ret = $CommandLineToArgvW->Call($lpCmdLine, $pNumArgs);
# lpCmdLine : LPCWSTR -> LPCWSTR
# pNumArgs : INT* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。