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

GetLongPathNameW

関数
短い形式のパスを長い形式のパスに変換する。
DLLKERNEL32.dll文字セットUnicode (-W)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

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

DWORD GetLongPathNameW(
    LPCWSTR lpszShortPath,
    LPWSTR lpszLongPath,   // optional
    DWORD cchBuffer
);

パラメーター

名前方向説明
lpszShortPathLPCWSTRin

変換するパス。

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

ヒント

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

lpszLongPathLPWSTRoutoptional

ロングパスを受け取るバッファーへのポインター。

lpszShortPath パラメーターで使用したものと同じバッファーを使用できます。

cchBufferDWORDinlpszLongPath が指すバッファーのサイズ。単位は TCHAR

戻り値の型: DWORD

公式ドキュメント

指定されたパスをロング形式に変換します。(Unicode)

戻り値

関数が成功した場合、戻り値は lpszLongPath にコピーされた文字列の長さ(TCHAR 単位)です。終端の null 文字は含まれません。

lpszLongPath バッファーがパスを格納するには小さすぎる場合、戻り値はパスと終端の null 文字を保持するために必要なバッファーのサイズ(TCHAR 単位)です。

ファイルが存在しないなど、その他の理由で関数が失敗した場合、戻り値は 0 です。拡張エラー情報を取得するには、 GetLastError を呼び出します。

解説(Remarks)

多くのファイルシステムでは、ショートファイル名にはチルダ()文字が含まれます。ただし、すべてのファイルシステムがこの規則に従うわけではありません。したがって、パスにチルダ()文字が含まれないからといって、 GetLongPathName の呼び出しを省略できると想定しないでください。

ファイルまたはディレクトリが存在するもののロングパスが見つからない場合、 GetLongPathName は成功し、lpszShortPath パラメーターが参照する文字列を lpszLongPath パラメーターが参照するバッファーにコピーします。

戻り値が cchBuffer で指定した値より大きい場合は、パスを保持するのに十分な大きさのバッファーを指定して関数を再度呼び出すことができます。このケースの例については、GetFullPathName の「サンプルコード」セクションを参照してください。

注意 このケースでの戻り値は終端の null 文字を含む長さですが、成功時の戻り値はカウントに終端の null 文字を含みません。
あるファイルまたはディレクトリへのアクセス権を持っていても、そのファイルまたはディレクトリの親ディレクトリの一部にアクセス権を持たない場合があります。その結果、GetLongPathName は、あるパスコンポーネントのロング名を判別するためにその親ディレクトリを照会できない場合に失敗することがあります。このチェックは、3 文字を超えるファイル拡張子を持つディレクトリコンポーネント、または合計の長さが 12 文字を超えるディレクトリコンポーネントに対してはスキップできます。詳細については、 ファイル、パス、および名前空間の名前付けショート名とロング名の比較セクションを参照してください。

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

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

GetLongPathName を使用する例については、GetFullPathName の「サンプルコード」セクションを参照してください。

メモ

fileapi.h ヘッダーは、GetLongPathName を、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして定義します。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、不一致が生じ、コンパイルエラーや実行時エラーを引き起こす可能性があります。詳細については、「関数プロトタイプの規則」を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は 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>

DWORD GetLongPathNameW(
    LPCWSTR lpszShortPath,
    LPWSTR lpszLongPath,   // optional
    DWORD cchBuffer
);
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
static extern uint GetLongPathNameW(
    [MarshalAs(UnmanagedType.LPWStr)] string lpszShortPath,   // LPCWSTR
    [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder lpszLongPath,   // LPWSTR optional, out
    uint cchBuffer   // DWORD
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function GetLongPathNameW(
    <MarshalAs(UnmanagedType.LPWStr)> lpszShortPath As String,   ' LPCWSTR
    <MarshalAs(UnmanagedType.LPWStr)> lpszLongPath As System.Text.StringBuilder,   ' LPWSTR optional, out
    cchBuffer As UInteger   ' DWORD
) As UInteger
End Function
' lpszShortPath : LPCWSTR
' lpszLongPath : LPWSTR optional, out
' cchBuffer : DWORD
Declare PtrSafe Function GetLongPathNameW Lib "kernel32" ( _
    ByVal lpszShortPath As LongPtr, _
    ByVal lpszLongPath As LongPtr, _
    ByVal cchBuffer As Long) 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

GetLongPathNameW = ctypes.windll.kernel32.GetLongPathNameW
GetLongPathNameW.restype = wintypes.DWORD
GetLongPathNameW.argtypes = [
    wintypes.LPCWSTR,  # lpszShortPath : LPCWSTR
    wintypes.LPWSTR,  # lpszLongPath : LPWSTR optional, out
    wintypes.DWORD,  # cchBuffer : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
GetLongPathNameW = Fiddle::Function.new(
  lib['GetLongPathNameW'],
  [
    Fiddle::TYPE_VOIDP,  # lpszShortPath : LPCWSTR
    Fiddle::TYPE_VOIDP,  # lpszLongPath : LPWSTR optional, out
    -Fiddle::TYPE_INT,  # cchBuffer : DWORD
  ],
  -Fiddle::TYPE_INT)
# Wide strings: pass str.encode("UTF-16LE") + "\x00\x00"
#[link(name = "kernel32")]
extern "system" {
    fn GetLongPathNameW(
        lpszShortPath: *const u16,  // LPCWSTR
        lpszLongPath: *mut u16,  // LPWSTR optional, out
        cchBuffer: u32  // DWORD
    ) -> u32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("KERNEL32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint GetLongPathNameW([MarshalAs(UnmanagedType.LPWStr)] string lpszShortPath, [MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder lpszLongPath, uint cchBuffer);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_GetLongPathNameW' -Namespace Win32 -PassThru
# $api::GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
#uselib "KERNEL32.dll"
#func global GetLongPathNameW "GetLongPathNameW" wptr, wptr, wptr
; GetLongPathNameW lpszShortPath, varptr(lpszLongPath), cchBuffer   ; 戻り値は stat
; lpszShortPath : LPCWSTR -> "wptr"
; lpszLongPath : LPWSTR optional, out -> "wptr"
; cchBuffer : DWORD -> "wptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "KERNEL32.dll"
#cfunc global GetLongPathNameW "GetLongPathNameW" wstr, var, int
; res = GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
; lpszShortPath : LPCWSTR -> "wstr"
; lpszLongPath : LPWSTR optional, out -> "var"
; cchBuffer : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; DWORD GetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWORD cchBuffer)
#uselib "KERNEL32.dll"
#cfunc global GetLongPathNameW "GetLongPathNameW" wstr, var, int
; res = GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
; lpszShortPath : LPCWSTR -> "wstr"
; lpszLongPath : LPWSTR optional, out -> "var"
; cchBuffer : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procGetLongPathNameW = kernel32.NewProc("GetLongPathNameW")
)

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

extern "kernel32" fn GetLongPathNameW(
    lpszShortPath: [*c]const u16, // LPCWSTR
    lpszLongPath: [*c]u16, // LPWSTR optional, out
    cchBuffer: u32 // DWORD
) callconv(std.os.windows.WINAPI) u32;
// Unicode(-W): UTF-16LE のヌル終端バッファ([*c]const u16)を渡す。
proc GetLongPathNameW(
    lpszShortPath: WideCString,  # LPCWSTR
    lpszLongPath: ptr uint16,  # LPWSTR optional, out
    cchBuffer: uint32  # DWORD
): uint32 {.importc: "GetLongPathNameW", stdcall, dynlib: "KERNEL32.dll".}
# Unicode(-W): WideCString は newWideCString("...") で生成。
pragma(lib, "kernel32");
extern(Windows)
uint GetLongPathNameW(
    const(wchar)* lpszShortPath,   // LPCWSTR
    wchar* lpszLongPath,   // LPWSTR optional, out
    uint cchBuffer   // DWORD
);
ccall((:GetLongPathNameW, "KERNEL32.dll"), stdcall, UInt32,
      (Cwstring, Ptr{UInt16}, UInt32),
      lpszShortPath, lpszLongPath, cchBuffer)
# lpszShortPath : LPCWSTR -> Cwstring
# lpszLongPath : LPWSTR optional, out -> Ptr{UInt16}
# cchBuffer : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
# Unicode(-W): Cwstring には transcode(UInt16, "...") 等で UTF-16 を渡す。
local ffi = require("ffi")
ffi.cdef[[
uint32_t GetLongPathNameW(
    const uint16_t* lpszShortPath,
    uint16_t* lpszLongPath,
    uint32_t cchBuffer);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
-- lpszShortPath : LPCWSTR
-- lpszLongPath : LPWSTR optional, out
-- cchBuffer : DWORD
-- 構造体/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 GetLongPathNameW = lib.func('__stdcall', 'GetLongPathNameW', 'uint32_t', ['str16', 'uint16_t *', 'uint32_t']);
// GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
// lpszShortPath : LPCWSTR -> 'str16'
// lpszLongPath : LPWSTR optional, out -> 'uint16_t *'
// cchBuffer : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  GetLongPathNameW: { parameters: ["buffer", "buffer", "u32"], result: "u32" },
});
// lib.symbols.GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer)
// lpszShortPath : LPCWSTR -> "buffer"
// lpszLongPath : LPWSTR optional, out -> "buffer"
// cchBuffer : DWORD -> "u32"
// 文字列は "buffer"。Unicode(-W) は new TextEncoder() ではなく UTF-16LE のバイト列(末尾に \x00\x00)を Uint8Array で渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
uint32_t GetLongPathNameW(
    const uint16_t* lpszShortPath,
    uint16_t* lpszLongPath,
    uint32_t cchBuffer);
C, "KERNEL32.dll");
// $ffi->GetLongPathNameW(lpszShortPath, lpszLongPath, cchBuffer);
// lpszShortPath : LPCWSTR
// lpszLongPath : LPWSTR optional, out
// cchBuffer : DWORD
// 構造体/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);
    int GetLongPathNameW(
        WString lpszShortPath,   // LPCWSTR
        char[] lpszLongPath,   // LPWSTR optional, out
        int cchBuffer   // DWORD
    );
}
// Unicode(-W): WString(入力)/char[](出力)で UTF-16 をマーシャリング。
@[Link("kernel32")]
lib LibKERNEL32
  fun GetLongPathNameW = GetLongPathNameW(
    lpszShortPath : UInt16*,   # LPCWSTR
    lpszLongPath : UInt16*,   # LPWSTR optional, out
    cchBuffer : UInt32   # DWORD
  ) : UInt32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef GetLongPathNameWNative = Uint32 Function(Pointer<Utf16>, Pointer<Utf16>, Uint32);
typedef GetLongPathNameWDart = int Function(Pointer<Utf16>, Pointer<Utf16>, int);
final GetLongPathNameW = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<GetLongPathNameWNative, GetLongPathNameWDart>('GetLongPathNameW');
// lpszShortPath : LPCWSTR -> Pointer<Utf16>
// lpszLongPath : LPWSTR optional, out -> Pointer<Utf16>
// cchBuffer : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function GetLongPathNameW(
  lpszShortPath: PWideChar;   // LPCWSTR
  lpszLongPath: PWideChar;   // LPWSTR optional, out
  cchBuffer: DWORD   // DWORD
): DWORD; stdcall;
  external 'KERNEL32.dll' name 'GetLongPathNameW';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "GetLongPathNameW"
  c_GetLongPathNameW :: CWString -> CWString -> Word32 -> IO Word32
-- lpszShortPath : LPCWSTR -> CWString
-- lpszLongPath : LPWSTR optional, out -> CWString
-- cchBuffer : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let getlongpathnamew =
  foreign "GetLongPathNameW"
    ((ptr uint16_t) @-> (ptr uint16_t) @-> uint32_t @-> returning uint32_t)
(* lpszShortPath : LPCWSTR -> (ptr uint16_t) *)
(* lpszLongPath : LPWSTR optional, out -> (ptr uint16_t) *)
(* cchBuffer : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("GetLongPathNameW" get-long-path-name-w :convention :stdcall) :uint32
  (lpsz-short-path (:string :encoding :utf-16le))   ; LPCWSTR
  (lpsz-long-path :pointer)   ; LPWSTR optional, out
  (cch-buffer :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $GetLongPathNameW = Win32::API::More->new('KERNEL32',
    'DWORD GetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWORD cchBuffer)');
# my $ret = $GetLongPathNameW->Call($lpszShortPath, $lpszLongPath, $cchBuffer);
# lpszShortPath : LPCWSTR -> LPCWSTR
# lpszLongPath : LPWSTR optional, out -> LPWSTR
# cchBuffer : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# Unicode(-W): LPCWSTR/LPWSTR は Win32::API が UTF-16 変換を行う。

関連項目

文字セット違い
公式の関連項目