WindowsプログラミングでCopyFileを使用としていてどうもうまくいかない場合あって、今回もそれにぶち当たったので今後のメモに書いておきます。
前提として、UTF-8における全角マイナスと全角チルダの問題(=いわゆる「波ダッシュ問題」) – 半径5メートルというのがあります。WindowsだとUTF-8の~が化けてしまうとのこと。
で、SJISではなくUnicode(UTF-16)だとOKそうなんで、パスをこのUnicodeで書けばいいのですけど、ネットワーク上だとやたらパスが長くなるのか何か知りませんがどうもやっぱりエラーになるということで、
とのことで早速やってみた。まずは基本。
[c language=”++”]
CopyFileW( L"D:\\~.wav", L"D:\\~1.wav", TRUE );
[/c]
で、ワイド文字拡張「
」を先頭に挿入[c language=”++”]
CopyFileW( L"\\\\?\\D:\\~.wav", L"\\\\?\\D:\\~1.wav", TRUE );
[/c]
ここまではOkなんだけど、ネットワークのパスになるとどうもだめで、
[c language=”++”]
CopyFileW( L"\\\\?\\\\\\127.0.0.1\\share\\~.wav", L"\\\\?\\D:\\~1.wav", TRUE );
[/c]
GetLastErrorで調べたところ、
ERROR_INVALID_NAME 123 0x0000007B ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
というエラーが出てくる。何か間違えているのかなと重い、CopyFileのページを見ると、「MSDN ライブラリの「」(ファイル名の規則)を参照してください。」と書いているものの、一体どこを参照すればいいのか困る自体に、、、
で、このページを探していたところどうやらMSDNライブラリの後の「」内は、TIPS/長いファイル名 – KOZの館 – Visual Basic Programming –のページたどり着く。
という文字だということがわかり、それを探していたところ、ネットワークパスの場合、
UNC名(ネットワークファイル名)に対しては、「
」を付加する
とのこと。で、「\\127.0.0.1」の前につけるだけでなく、最初の「\\」を取ることとのこと。結果的に、以下のコードで動くようだ。
[c language=”++”]
CopyFileW( L"\\\\?\\UNC\\127.0.0.1\\share\\~.wav", L"\\\\?\\D:\\~1.wav", TRUE );
[/c]
UNCってなんだろう~って調べてたところ、UNCとは【Universal Naming Convention】 – 意味/解説/説明/定義 : IT用語辞典で言っているようにUniversal Naming Conventionのようだ。
また、PHPでこの波ダッシュ「~」を変換している人もいるようだ。波ダッシュ対策 – ここにおいておくね.php>(�・▽・`)