Win32 API 日本語リファレンス
ホームStorage.FileSystem › MoveFileTransactedW

MoveFileTransactedW

関数
トランザクション内でファイルを移動・改名する(Unicode版)。
DLLKERNEL32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows Vista 以降

シグネチャ

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

BOOL MoveFileTransactedW(
    LPCWSTR lpExistingFileName,
    LPCWSTR lpNewFileName,   // optional
    LPPROGRESS_ROUTINE lpProgressRoutine,   // optional
    void* lpData,   // optional
    MOVE_FILE_FLAGS dwFlags,
    HANDLE hTransaction
);

パラメーター

名前方向説明
lpExistingFileNameLPCWSTRin

ローカルコンピューター上の既存のファイルまたはディレクトリの現在の名前。

既定では、名前は MAX_PATH 文字に制限されます。この制限を 32,767 ワイド文字まで拡張するには、パスの先頭に "\\?\" を付加します。詳細については、ファイル、パス、および名前空間の名前付け を参照してください。

ヒント

Windows 10 バージョン 1607 以降では、"\\?\" を付加することなく MAX_PATH の制限を解除するようにオプトインできます。詳細については、ファイル、パス、および名前空間の名前付け の「Maximum Path Length Limitation」セクションを参照してください。

lpNewFileNameLPCWSTRinoptional

ファイルまたはディレクトリの新しい名前。新しい名前は既に存在していてはなりません。新しいファイルは 別のファイルシステムまたはドライブ上にあってもかまいません。新しいディレクトリは同じドライブ上になければなりません。

既定では、名前は MAX_PATH 文字に制限されます。この制限を 32,767 ワイド文字まで拡張するには、パスの先頭に "\\?\" を付加します。詳細については、ファイル、パス、および名前空間の名前付け を参照してください。

ヒント

Windows 10 バージョン 1607 以降では、"\\?\" を付加することなく MAX_PATH の制限を解除するようにオプトインできます。詳細については、ファイル、パス、および名前空間の名前付け の「Maximum Path Length Limitation」セクションを参照してください。

lpProgressRoutineLPPROGRESS_ROUTINEinoptionalファイルの別の部分が移動されるたびに呼び出される CopyProgressRoutine コールバック 関数へのポインター。このコールバック関数は、操作の進行状況を表示するユーザーインターフェイスを提供する場合に 役立ちます。このパラメーターには NULL を指定できます。
lpDatavoid*inoptionalCopyProgressRoutine コールバック関数に渡される引数。この パラメーターには NULL を指定できます。
dwFlagsMOVE_FILE_FLAGSin

移動オプション。このパラメーターには、次の値を 1 つ以上指定できます。

意味
MOVEFILE_COPY_ALLOWED
2 (0x2)
ファイルを別のボリュームに移動する場合、この関数は CopyFile 関数および DeleteFile 関数を使用して移動をシミュレートします。

ファイルが別のボリュームに正常にコピーされ、元のファイルを削除できなかった場合、 この関数は成功し、ソースファイルはそのまま残されます。

この値は MOVEFILE_DELAY_UNTIL_REBOOT と併用できません。

MOVEFILE_CREATE_HARDLINK
16 (0x10)
将来の使用のために予約されています。
MOVEFILE_DELAY_UNTIL_REBOOT
4 (0x4)
システムは、オペレーティングシステムが再起動されるまでファイルを移動しません。システムは、AUTOCHK の実行直後、 ただしページングファイルの作成前にファイルを移動します。その結果、このパラメーターを使用すると、 以前の起動時のページングファイルを削除できます。

この値は、プロセスが administrators グループに属するユーザー、または LocalSystem アカウントの コンテキストにある場合にのみ使用できます。

この値は MOVEFILE_COPY_ALLOWED と併用できません。

トランザクションされるのは、「Remarks」セクションで詳述されているレジストリ値への書き込み操作です。 ファイルの移動は、トランザクションの完了後、コンピューターの再起動時に完了します。

MOVEFILE_REPLACE_EXISTING
1 (0x1)
lpNewFileName という名前のファイルが存在する場合、この関数はその内容を lpExistingFileName ファイルの内容で置き換えます。

この値は、lpNewFileName または lpExistingFileName がディレクトリを指定している場合は使用できません。

MOVEFILE_WRITE_THROUGH
8 (0x8)
MoveFileTransacted の呼び出しは、 コミット操作が完了した時点でファイル移動操作が完了することを意味します。このフラグは不要であり、指定しても 操作が遅くなる以外に悪影響はありません。この関数は、ファイルがディスク上で実際に移動されるまで 制御を返しません。

この値を設定すると、コピーと削除の操作として実行される移動が、関数が制御を返す前にディスクへフラッシュ されることが保証されます。フラッシュはコピー操作の最後に行われます。

この値は、MOVEFILE_DELAY_UNTIL_REBOOT が設定されている場合は効果がありません。

hTransactionHANDLEinトランザクションへのハンドル。このハンドルは CreateTransaction 関数によって返されます。

戻り値の型: BOOL

公式ドキュメント

既存のファイル、またはディレクトリ(その子を含む)をトランザクション操作として移動します。(Unicode)

戻り値

関数が成功すると、戻り値は 0 以外になります。

関数が失敗すると、戻り値は 0 になります。拡張エラー情報を取得するには、 GetLastError を呼び出します。

ボリューム間でファイルを移動する際、ユーザーが操作をキャンセルしたために lpProgressRoutinePROGRESS_CANCEL を返した場合、 MoveFileTransacted は 0 を返し、 GetLastErrorERROR_REQUEST_ABORTED を返します。既存のファイルはそのまま残されます。

ボリューム間でファイルを移動する際、ユーザーが操作を停止したために lpProgressRoutinePROGRESS_STOP を返した場合、 MoveFileTransacted は 0 を返し、 GetLastErrorERROR_REQUEST_ABORTED を返します。既存のファイルはそのまま残されます。

解説(Remarks)

dwFlags パラメーターに MOVEFILE_DELAY_UNTIL_REBOOT が指定されている場合、 MoveFileTransacted はレジストリにアクセスできないと失敗します。この 関数は、再起動時に名前を変更するファイルの場所を、次のレジストリ値にトランザクション的に 格納します: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

このレジストリ値は REG_MULTI_SZ 型です。各名前変更操作は、名前変更が削除であるかどうかに応じて、 次のいずれかの NULL 終端文字列を格納します:

szDstFile\0\0

szSrcFile\0szDstFile\0

文字列 szDstFile\0\0 は、ファイル szDstFile が再起動時に削除されることを示します。

文字列 szSrcFile\0szDstFile\0 は、 szSrcFile が再起動時に szDstFile へ名前変更されることを示します。

\0\0 は REG_MULTI_SZ ノードでは技術的には許可されていませんが、 ファイルが null の名前に変更されると見なされるため、使用できます。
システムはこれらのレジストリエントリを使用して、操作が発行されたのと同じ順序で再起動時に操作を完了します。 MOVEFILE_DELAY_UNTIL_REBOOT フラグの使用方法の詳細については、 MoveFileWithProgress を参照してください。

ファイルがボリューム間で移動される場合、 MoveFileTransacted はファイルとともにセキュリティ 記述子を移動しません。ファイルには、移動先ディレクトリの既定のセキュリティ記述子が割り当てられます。

この関数は、MOVEFILE_FAIL_IF_NOT_TRACKABLE フラグを指定すると常に失敗します。 トラッキングは TxF ではサポートされていません。

Windows 8 および Windows Server 2012 では、この関数は次のテクノロジーでサポートされています。

テクノロジー サポート
Server Message Block (SMB) 3.0 プロトコル いいえ
SMB 3.0 トランスペアレントフェールオーバー (TFO) いいえ
スケールアウトファイル共有を使用した SMB 3.0 (SO) いいえ
クラスター共有ボリュームファイルシステム (CsvFS) いいえ
回復性ファイルシステム (ReFS) いいえ

SMB 3.0 は TxF をサポートしていません。

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

各言語での呼び出し定義

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

BOOL MoveFileTransactedW(
    LPCWSTR lpExistingFileName,
    LPCWSTR lpNewFileName,   // optional
    LPPROGRESS_ROUTINE lpProgressRoutine,   // optional
    void* lpData,   // optional
    MOVE_FILE_FLAGS dwFlags,
    HANDLE hTransaction
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern bool MoveFileTransactedW(
    [MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName,   // LPCWSTR
    [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName,   // LPCWSTR optional
    IntPtr lpProgressRoutine,   // LPPROGRESS_ROUTINE optional
    IntPtr lpData,   // void* optional
    uint dwFlags,   // MOVE_FILE_FLAGS
    IntPtr hTransaction   // HANDLE
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function MoveFileTransactedW(
    <MarshalAs(UnmanagedType.LPWStr)> lpExistingFileName As String,   ' LPCWSTR
    <MarshalAs(UnmanagedType.LPWStr)> lpNewFileName As String,   ' LPCWSTR optional
    lpProgressRoutine As IntPtr,   ' LPPROGRESS_ROUTINE optional
    lpData As IntPtr,   ' void* optional
    dwFlags As UInteger,   ' MOVE_FILE_FLAGS
    hTransaction As IntPtr   ' HANDLE
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' lpExistingFileName : LPCWSTR
' lpNewFileName : LPCWSTR optional
' lpProgressRoutine : LPPROGRESS_ROUTINE optional
' lpData : void* optional
' dwFlags : MOVE_FILE_FLAGS
' hTransaction : HANDLE
Declare PtrSafe Function MoveFileTransactedW Lib "kernel32" ( _
    ByVal lpExistingFileName As LongPtr, _
    ByVal lpNewFileName As LongPtr, _
    ByVal lpProgressRoutine As LongPtr, _
    ByVal lpData As LongPtr, _
    ByVal dwFlags As Long, _
    ByVal hTransaction 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

MoveFileTransactedW = ctypes.windll.kernel32.MoveFileTransactedW
MoveFileTransactedW.restype = wintypes.BOOL
MoveFileTransactedW.argtypes = [
    wintypes.LPCWSTR,  # lpExistingFileName : LPCWSTR
    wintypes.LPCWSTR,  # lpNewFileName : LPCWSTR optional
    ctypes.c_void_p,  # lpProgressRoutine : LPPROGRESS_ROUTINE optional
    ctypes.POINTER(None),  # lpData : void* optional
    wintypes.DWORD,  # dwFlags : MOVE_FILE_FLAGS
    wintypes.HANDLE,  # hTransaction : HANDLE
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
MoveFileTransactedW = Fiddle::Function.new(
  lib['MoveFileTransactedW'],
  [
    Fiddle::TYPE_VOIDP,  # lpExistingFileName : LPCWSTR
    Fiddle::TYPE_VOIDP,  # lpNewFileName : LPCWSTR optional
    Fiddle::TYPE_VOIDP,  # lpProgressRoutine : LPPROGRESS_ROUTINE optional
    Fiddle::TYPE_VOIDP,  # lpData : void* optional
    -Fiddle::TYPE_INT,  # dwFlags : MOVE_FILE_FLAGS
    Fiddle::TYPE_VOIDP,  # hTransaction : HANDLE
  ],
  Fiddle::TYPE_INT)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "kernel32")]
extern "system" {
    fn MoveFileTransactedW(
        lpExistingFileName: *const u16,  // LPCWSTR
        lpNewFileName: *const u16,  // LPCWSTR optional
        lpProgressRoutine: *const core::ffi::c_void,  // LPPROGRESS_ROUTINE optional
        lpData: *mut (),  // void* optional
        dwFlags: u32,  // MOVE_FILE_FLAGS
        hTransaction: *mut core::ffi::c_void  // HANDLE
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool MoveFileTransactedW([MarshalAs(UnmanagedType.LPWStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPWStr)] string lpNewFileName, IntPtr lpProgressRoutine, IntPtr lpData, uint dwFlags, IntPtr hTransaction);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_MoveFileTransactedW' -Namespace Win32 -PassThru
# $api::MoveFileTransactedW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
#uselib "KERNEL32.dll"
#func global MoveFileTransactedW "MoveFileTransactedW" wptr, wptr, wptr, wptr, wptr, wptr
; MoveFileTransactedW lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction   ; 戻り値は stat
; lpExistingFileName : LPCWSTR -> "wptr"
; lpNewFileName : LPCWSTR optional -> "wptr"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "wptr"
; lpData : void* optional -> "wptr"
; dwFlags : MOVE_FILE_FLAGS -> "wptr"
; hTransaction : HANDLE -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global MoveFileTransactedW "MoveFileTransactedW" wstr, wstr, sptr, sptr, int, sptr
; res = MoveFileTransactedW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
; lpExistingFileName : LPCWSTR -> "wstr"
; lpNewFileName : LPCWSTR optional -> "wstr"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "sptr"
; lpData : void* optional -> "sptr"
; dwFlags : MOVE_FILE_FLAGS -> "int"
; hTransaction : HANDLE -> "sptr"
; BOOL MoveFileTransactedW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, void* lpData, MOVE_FILE_FLAGS dwFlags, HANDLE hTransaction)
#uselib "KERNEL32.dll"
#cfunc global MoveFileTransactedW "MoveFileTransactedW" wstr, wstr, intptr, intptr, int, intptr
; res = MoveFileTransactedW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
; lpExistingFileName : LPCWSTR -> "wstr"
; lpNewFileName : LPCWSTR optional -> "wstr"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "intptr"
; lpData : void* optional -> "intptr"
; dwFlags : MOVE_FILE_FLAGS -> "int"
; hTransaction : HANDLE -> "intptr"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procMoveFileTransactedW = kernel32.NewProc("MoveFileTransactedW")
)

// lpExistingFileName (LPCWSTR), lpNewFileName (LPCWSTR optional), lpProgressRoutine (LPPROGRESS_ROUTINE optional), lpData (void* optional), dwFlags (MOVE_FILE_FLAGS), hTransaction (HANDLE)
r1, _, err := procMoveFileTransactedW.Call(
	uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpExistingFileName))),
	uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpNewFileName))),
	uintptr(lpProgressRoutine),
	uintptr(lpData),
	uintptr(dwFlags),
	uintptr(hTransaction),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function MoveFileTransactedW(
  lpExistingFileName: PWideChar;   // LPCWSTR
  lpNewFileName: PWideChar;   // LPCWSTR optional
  lpProgressRoutine: Pointer;   // LPPROGRESS_ROUTINE optional
  lpData: Pointer;   // void* optional
  dwFlags: DWORD;   // MOVE_FILE_FLAGS
  hTransaction: THandle   // HANDLE
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'MoveFileTransactedW';
result := DllCall("KERNEL32\MoveFileTransactedW"
    , "WStr", lpExistingFileName   ; LPCWSTR
    , "WStr", lpNewFileName   ; LPCWSTR optional
    , "Ptr", lpProgressRoutine   ; LPPROGRESS_ROUTINE optional
    , "Ptr", lpData   ; void* optional
    , "UInt", dwFlags   ; MOVE_FILE_FLAGS
    , "Ptr", hTransaction   ; HANDLE
    , "Int")   ; return: BOOL
●MoveFileTransactedW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction) = DLL("KERNEL32.dll", "bool MoveFileTransactedW(char*, char*, void*, void*, dword, void*)")
# 呼び出し: MoveFileTransactedW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
# lpExistingFileName : LPCWSTR -> "char*"
# lpNewFileName : LPCWSTR optional -> "char*"
# lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "void*"
# lpData : void* optional -> "void*"
# dwFlags : MOVE_FILE_FLAGS -> "dword"
# hTransaction : HANDLE -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
# ※-W(Unicode)関数。なでしこ1はANSIのため -A 版の利用を推奨。
const std = @import("std");

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

typedef MoveFileTransactedWNative = Int32 Function(Pointer<Utf16>, Pointer<Utf16>, Pointer<Void>, Pointer<Void>, Uint32, Pointer<Void>);
typedef MoveFileTransactedWDart = int Function(Pointer<Utf16>, Pointer<Utf16>, Pointer<Void>, Pointer<Void>, int, Pointer<Void>);
final MoveFileTransactedW = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<MoveFileTransactedWNative, MoveFileTransactedWDart>('MoveFileTransactedW');
// lpExistingFileName : LPCWSTR -> Pointer<Utf16>
// lpNewFileName : LPCWSTR optional -> Pointer<Utf16>
// lpProgressRoutine : LPPROGRESS_ROUTINE optional -> Pointer<Void>
// lpData : void* optional -> Pointer<Void>
// dwFlags : MOVE_FILE_FLAGS -> Uint32
// hTransaction : HANDLE -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function MoveFileTransactedW(
  lpExistingFileName: PWideChar;   // LPCWSTR
  lpNewFileName: PWideChar;   // LPCWSTR optional
  lpProgressRoutine: Pointer;   // LPPROGRESS_ROUTINE optional
  lpData: Pointer;   // void* optional
  dwFlags: DWORD;   // MOVE_FILE_FLAGS
  hTransaction: THandle   // HANDLE
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'MoveFileTransactedW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "MoveFileTransactedW"
  c_MoveFileTransactedW :: CWString -> CWString -> Ptr () -> Ptr () -> Word32 -> Ptr () -> IO CInt
-- lpExistingFileName : LPCWSTR -> CWString
-- lpNewFileName : LPCWSTR optional -> CWString
-- lpProgressRoutine : LPPROGRESS_ROUTINE optional -> Ptr ()
-- lpData : void* optional -> Ptr ()
-- dwFlags : MOVE_FILE_FLAGS -> Word32
-- hTransaction : HANDLE -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let movefiletransactedw =
  foreign "MoveFileTransactedW"
    ((ptr uint16_t) @-> (ptr uint16_t) @-> (ptr void) @-> (ptr void) @-> uint32_t @-> (ptr void) @-> returning int32_t)
(* lpExistingFileName : LPCWSTR -> (ptr uint16_t) *)
(* lpNewFileName : LPCWSTR optional -> (ptr uint16_t) *)
(* lpProgressRoutine : LPPROGRESS_ROUTINE optional -> (ptr void) *)
(* lpData : void* optional -> (ptr void) *)
(* dwFlags : MOVE_FILE_FLAGS -> uint32_t *)
(* hTransaction : HANDLE -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("MoveFileTransactedW" move-file-transacted-w :convention :stdcall) :int32
  (lp-existing-file-name (:string :encoding :utf-16le))   ; LPCWSTR
  (lp-new-file-name (:string :encoding :utf-16le))   ; LPCWSTR optional
  (lp-progress-routine :pointer)   ; LPPROGRESS_ROUTINE optional
  (lp-data :pointer)   ; void* optional
  (dw-flags :uint32)   ; MOVE_FILE_FLAGS
  (h-transaction :pointer))   ; HANDLE
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $MoveFileTransactedW = Win32::API::More->new('KERNEL32',
    'BOOL MoveFileTransactedW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, LPVOID lpProgressRoutine, LPVOID lpData, DWORD dwFlags, HANDLE hTransaction)');
# my $ret = $MoveFileTransactedW->Call($lpExistingFileName, $lpNewFileName, $lpProgressRoutine, $lpData, $dwFlags, $hTransaction);
# lpExistingFileName : LPCWSTR -> LPCWSTR
# lpNewFileName : LPCWSTR optional -> LPCWSTR
# lpProgressRoutine : LPPROGRESS_ROUTINE optional -> LPVOID
# lpData : void* optional -> LPVOID
# dwFlags : MOVE_FILE_FLAGS -> DWORD
# hTransaction : HANDLE -> HANDLE
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

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