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

ShellExecuteExW

関数
指定したファイルやプログラムをシェル経由で実行する。
DLLSHELL32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

// SHELL32.dll  (Unicode / -W)
#include <windows.h>

BOOL ShellExecuteExW(
    SHELLEXECUTEINFOW* pExecInfo
);

パラメーター

名前方向説明
pExecInfoSHELLEXECUTEINFOW*inout実行するアプリケーションに関する情報を格納および受け取る SHELLEXECUTEINFO 構造体へのポインター。

戻り値の型: BOOL

公式ドキュメント

指定したファイルに対して操作を実行します。(ShellExecuteExW)

戻り値

型: BOOL

成功した場合は TRUE を返します。それ以外の場合は FALSE を返します。拡張エラー情報を取得するには GetLastError を呼び出してください。

解説(Remarks)

ShellExecuteEx は、Component Object Model (COM) を使用して有効化される Shell 拡張機能 (データソース、コンテキストメニューハンドラー、動詞の実装) に実行を委譲できるため、ShellExecuteEx を呼び出す前に COM を初期化しておく必要があります。一部の Shell 拡張機能は COM のシングルスレッドアパートメント (STA) 型を必要とします。その場合、COM は次のように初期化する必要があります。

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)

ShellExecuteEx がこのような Shell 拡張機能を使用しない場合もあり、その場合は COM をまったく初期化する必要はありません。とはいえ、この関数を使用する前には常に COM を初期化しておくのが良い習慣です。

DLL がプロセスに読み込まれると、ローダーロックと呼ばれるロックを取得します。DllMain 関数は常にローダーロックの下で実行されます。ローダーロックを保持している間は ShellExecuteEx を呼び出さないことが重要です。ShellExecuteEx は拡張可能であるため、ローダーロックが存在する状況では正しく機能しないコードが読み込まれる可能性があり、デッドロック、ひいてはスレッドの応答停止を引き起こすおそれがあります。

複数のモニターを使用している場合、HWND を指定し、lpExecInfo が指す SHELLEXECUTEINFO 構造体の lpVerb メンバーを "Properties" に設定すると、ShellExecuteEx によって作成されるウィンドウが正しい位置に表示されない場合があります。

関数が成功すると、SHELLEXECUTEINFO 構造体の hInstApp メンバーに 32 より大きい値が設定されます。関数が失敗した場合、hInstApp には失敗の原因を最もよく示す SE_ERR_XXX エラー値が設定されます。hInstApp は 16 ビット Windows アプリケーションとの互換性のために HINSTANCE として宣言されていますが、本来の HINSTANCE ではありません。int にのみキャストでき、値 32 または SE_ERR_XXX エラーコードとのみ比較できます。

SE_ERR_XXX エラー値は ShellExecute との互換性のために用意されています。より正確なエラー情報を取得するには GetLastError を使用してください。次のいずれかの値が返される場合があります。

エラー 説明
ERROR_FILE_NOT_FOUND 指定されたファイルが見つかりませんでした。
ERROR_PATH_NOT_FOUND 指定されたパスが見つかりませんでした。
ERROR_DDE_FAIL 動的データ交換 (DDE) トランザクションが失敗しました。
ERROR_NO_ASSOCIATION 指定されたファイル名拡張子に関連付けられたアプリケーションがありません。
ERROR_ACCESS_DENIED 指定されたファイルへのアクセスが拒否されました。
ERROR_DLL_NOT_FOUND アプリケーションの実行に必要なライブラリファイルの 1 つが見つかりません。
ERROR_CANCELLED 関数がユーザーに追加情報の入力を求めましたが、ユーザーが要求をキャンセルしました。
ERROR_NOT_ENOUGH_MEMORY 指定された操作を実行するのに十分なメモリがありません。
ERROR_SHARING_VIOLATION 共有違反が発生しました。

URL からのアイテムのオープン URL が渡されたときに有効化されるよう、アプリケーションを登録できます。また、アプリケーションがサポートするプロトコルを指定することもできます。詳細については Application Registration を参照してください。

サイトチェーンのサポート Windows 8 以降では、ShellExecuteEx 関数にサイトチェーンポインターを指定して、そのサイトのサービスによるアイテムの有効化をサポートできます。詳細については Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO) を参照してください。

メモ

shellapi.h ヘッダーは ShellExecuteEx をエイリアスとして定義し、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択します。エンコーディング中立なエイリアスの使用と、エンコーディング中立でないコードを混在させると、不一致が生じてコンパイルエラーや実行時エラーの原因となる場合があります。詳細については Conventions for Function Prototypes を参照してください。

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

各言語での呼び出し定義

// SHELL32.dll  (Unicode / -W)
#include <windows.h>

BOOL ShellExecuteExW(
    SHELLEXECUTEINFOW* pExecInfo
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("SHELL32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern bool ShellExecuteExW(
    IntPtr pExecInfo   // SHELLEXECUTEINFOW* in/out
);
<DllImport("SHELL32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function ShellExecuteExW(
    pExecInfo As IntPtr   ' SHELLEXECUTEINFOW* in/out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' pExecInfo : SHELLEXECUTEINFOW* in/out
Declare PtrSafe Function ShellExecuteExW Lib "shell32" ( _
    ByVal pExecInfo As LongPtr) As Long
' Unicode(W): 文字列は ByVal As LongPtr とし StrPtr(unicodeStr) を渡す
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

ShellExecuteExW = ctypes.windll.shell32.ShellExecuteExW
ShellExecuteExW.restype = wintypes.BOOL
ShellExecuteExW.argtypes = [
    ctypes.c_void_p,  # pExecInfo : SHELLEXECUTEINFOW* in/out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('SHELL32.dll')
ShellExecuteExW = Fiddle::Function.new(
  lib['ShellExecuteExW'],
  [
    Fiddle::TYPE_VOIDP,  # pExecInfo : SHELLEXECUTEINFOW* in/out
  ],
  Fiddle::TYPE_INT)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "shell32")]
extern "system" {
    fn ShellExecuteExW(
        pExecInfo: *mut SHELLEXECUTEINFOW  // SHELLEXECUTEINFOW* in/out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("SHELL32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ShellExecuteExW(IntPtr pExecInfo);
"@
$api = Add-Type -MemberDefinition $sig -Name 'SHELL32_ShellExecuteExW' -Namespace Win32 -PassThru
# $api::ShellExecuteExW(pExecInfo)
#uselib "SHELL32.dll"
#func global ShellExecuteExW "ShellExecuteExW" wptr
; ShellExecuteExW varptr(pExecInfo)   ; 戻り値は stat
; pExecInfo : SHELLEXECUTEINFOW* in/out -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "SHELL32.dll"
#cfunc global ShellExecuteExW "ShellExecuteExW" var
; res = ShellExecuteExW(pExecInfo)
; pExecInfo : SHELLEXECUTEINFOW* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; BOOL ShellExecuteExW(SHELLEXECUTEINFOW* pExecInfo)
#uselib "SHELL32.dll"
#cfunc global ShellExecuteExW "ShellExecuteExW" var
; res = ShellExecuteExW(pExecInfo)
; pExecInfo : SHELLEXECUTEINFOW* in/out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	shell32 = windows.NewLazySystemDLL("SHELL32.dll")
	procShellExecuteExW = shell32.NewProc("ShellExecuteExW")
)

// pExecInfo (SHELLEXECUTEINFOW* in/out)
r1, _, err := procShellExecuteExW.Call(
	uintptr(pExecInfo),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function ShellExecuteExW(
  pExecInfo: Pointer   // SHELLEXECUTEINFOW* in/out
): BOOL; stdcall;
  external 'SHELL32.dll' name 'ShellExecuteExW';
result := DllCall("SHELL32\ShellExecuteExW"
    , "Ptr", pExecInfo   ; SHELLEXECUTEINFOW* in/out
    , "Int")   ; return: BOOL
●ShellExecuteExW(pExecInfo) = DLL("SHELL32.dll", "bool ShellExecuteExW(void*)")
# 呼び出し: ShellExecuteExW(pExecInfo)
# pExecInfo : SHELLEXECUTEINFOW* in/out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。
const std = @import("std");

extern "shell32" fn ShellExecuteExW(
    pExecInfo: [*c]SHELLEXECUTEINFOW // SHELLEXECUTEINFOW* in/out
) callconv(std.os.windows.WINAPI) i32;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。
proc ShellExecuteExW(
    pExecInfo: ptr SHELLEXECUTEINFOW  # SHELLEXECUTEINFOW* in/out
): int32 {.importc: "ShellExecuteExW", stdcall, dynlib: "SHELL32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。
pragma(lib, "shell32");
extern(Windows)
int ShellExecuteExW(
    SHELLEXECUTEINFOW* pExecInfo   // SHELLEXECUTEINFOW* in/out
);
ccall((:ShellExecuteExW, "SHELL32.dll"), stdcall, Int32,
      (Ptr{SHELLEXECUTEINFOW},),
      pExecInfo)
# pExecInfo : SHELLEXECUTEINFOW* in/out -> Ptr{SHELLEXECUTEINFOW}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。
local ffi = require("ffi")
ffi.cdef[[
int32_t ShellExecuteExW(
    void* pExecInfo);
]]
local shell32 = ffi.load("shell32")
-- shell32.ShellExecuteExW(pExecInfo)
-- pExecInfo : SHELLEXECUTEINFOW* in/out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
-- Unicode(-W): uint16_t* には UTF-16LE のバッファ(ffi.new("uint16_t[?]", ...))を渡す。
const koffi = require('koffi');
const lib = koffi.load('SHELL32.dll');
const ShellExecuteExW = lib.func('__stdcall', 'ShellExecuteExW', 'int32_t', ['void *']);
// ShellExecuteExW(pExecInfo)
// pExecInfo : SHELLEXECUTEINFOW* in/out -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("SHELL32.dll", {
  ShellExecuteExW: { parameters: ["pointer"], result: "i32" },
});
// lib.symbols.ShellExecuteExW(pExecInfo)
// pExecInfo : SHELLEXECUTEINFOW* in/out -> "pointer"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t ShellExecuteExW(
    void* pExecInfo);
C, "SHELL32.dll");
// $ffi->ShellExecuteExW(pExecInfo);
// pExecInfo : SHELLEXECUTEINFOW* in/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, W32APIOptions.UNICODE_OPTIONS);
    boolean ShellExecuteExW(
        Pointer pExecInfo   // SHELLEXECUTEINFOW* in/out
    );
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。
@[Link("shell32")]
lib LibSHELL32
  fun ShellExecuteExW = ShellExecuteExW(
    pExecInfo : SHELLEXECUTEINFOW*   # SHELLEXECUTEINFOW* in/out
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef ShellExecuteExWNative = Int32 Function(Pointer<Void>);
typedef ShellExecuteExWDart = int Function(Pointer<Void>);
final ShellExecuteExW = DynamicLibrary.open('SHELL32.dll')
    .lookupFunction<ShellExecuteExWNative, ShellExecuteExWDart>('ShellExecuteExW');
// pExecInfo : SHELLEXECUTEINFOW* in/out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function ShellExecuteExW(
  pExecInfo: Pointer   // SHELLEXECUTEINFOW* in/out
): BOOL; stdcall;
  external 'SHELL32.dll' name 'ShellExecuteExW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "ShellExecuteExW"
  c_ShellExecuteExW :: Ptr () -> IO CInt
-- pExecInfo : SHELLEXECUTEINFOW* in/out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let shellexecuteexw =
  foreign "ShellExecuteExW"
    ((ptr void) @-> returning int32_t)
(* pExecInfo : SHELLEXECUTEINFOW* in/out -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library shell32 (t "SHELL32.dll"))
(cffi:use-foreign-library shell32)

(cffi:defcfun ("ShellExecuteExW" shell-execute-ex-w :convention :stdcall) :int32
  (p-exec-info :pointer))   ; SHELLEXECUTEINFOW* in/out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $ShellExecuteExW = Win32::API::More->new('SHELL32',
    'BOOL ShellExecuteExW(LPVOID pExecInfo)');
# my $ret = $ShellExecuteExW->Call($pExecInfo);
# pExecInfo : SHELLEXECUTEINFOW* in/out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

文字セット違い
類似 API
公式の関連項目
使用する型