CommandLineToArgvW
関数シグネチャ
// SHELL32.dll
#include <windows.h>
LPWSTR* CommandLineToArgvW(
LPCWSTR lpCmdLine,
INT* pNumArgs
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| lpCmdLine | LPCWSTR | in | 完全なコマンドラインを含む null 終端の Unicode 文字列へのポインター。このパラメーターが空文字列の場合、関数は現在の実行可能ファイルへのパスを返します。 |
| pNumArgs | INT* | out | 返される配列要素の数を受け取る int へのポインター。argc に相当します。 |
戻り値の型: LPWSTR*
公式ドキュメント
Unicode のコマンドライン文字列を解析し、標準 C ランタイムの argv および argc の値と同様の方法で、コマンドライン引数へのポインターの配列と、その引数の個数を返します。
戻り値
型: LPWSTR*
argv に相当する、LPWSTR 値の配列へのポインター。
関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには、GetLastError を呼び出します。
解説(Remarks)
CommandLineToArgvW が返すアドレスは、LPWSTR 値の配列の先頭要素のアドレスです。この配列内のポインターの数は pNumArgs によって示されます。null 終端の Unicode 文字列への各ポインターは、コマンドライン上で見つかった個々の引数を表します。
CommandLineToArgvW は、引数文字列へのポインターと引数文字列自体のために連続したメモリブロックを割り当てます。呼び出し側のアプリケーションは、引数リストが不要になったら、それが使用しているメモリを解放する必要があります。メモリを解放するには、LocalFree 関数を 1 回呼び出します。
argv と argc の引数の規則の詳細については、Argument Definitions および Parsing C Command-Line Arguments を参照してください。
lpCmdLine パラメーターとして使用するのに適したコマンドライン文字列を取得するには、GetCommandLineW 関数を使用できます。
この関数は、プログラム名を含むコマンドラインを受け付けます。プログラム名は引用符で囲んでも囲まなくてもかまいません。
CommandLineToArgvW は、バックスラッシュ文字の後に引用符文字 (") が続く場合に、それらを特別に解釈します。この解釈では、直前の引数が有効なファイルシステムのパスであることを前提としており、そうでない場合は予測できない動作をする可能性があります。
この特別な解釈は、パーサーが追跡する「引用符内」モードを制御します。このモードがオフの場合、空白は現在の引数を終了させます。オンの場合、空白は他のすべての文字と同様に引数に追加されます。
- 2n 個のバックスラッシュの後に引用符が続く場合、n 個のバックスラッシュの後に引用の開始/終了が生成されます。これは解析された引数の一部にはならず、「引用符内」モードを切り替えます。
- (2n) + 1 個のバックスラッシュの後に引用符が続く場合、やはり n 個のバックスラッシュの後にリテラルの引用符 (") が生成されます。これは「引用符内」モードを切り替えません。
- 引用符が続かない n 個のバックスラッシュは、単に n 個のバックスラッシュを生成します。
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 公式リファレンス: 英語 (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 方式にも切替可。#uselib "SHELL32.dll" #cfunc global CommandLineToArgvW "CommandLineToArgvW" wstr, sptr ; res = CommandLineToArgvW(lpCmdLine, varptr(pNumArgs)) ; lpCmdLine : LPCWSTR -> "wstr" ; pNumArgs : INT* out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは 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 方式にも切替可。; LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, INT* pNumArgs) #uselib "SHELL32.dll" #cfunc global CommandLineToArgvW "CommandLineToArgvW" wstr, intptr ; res = CommandLineToArgvW(lpCmdLine, varptr(pNumArgs)) ; lpCmdLine : LPCWSTR -> "wstr" ; pNumArgs : INT* out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは 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 を使用。