- ベストアンサー
WindowsAPI FileCopyOperation Vistaで動作が違います
WindowsAPI FileCopyOperationをWindows2000で使っていたのですが、Vistaで動作させたら、若干動作が違います。 コピー元のファイルがない場合、2000では、「ファイルがコピーできません・・・」というエラーメッセージが表示されるだけですが、Vistaでは、「・・・確認してから、操作を再実行してください」というメッセージで、「再試行」、「キャンセル」という二つのボタンから選べるようになっています。(再試行を選択しても何もおきません) 従来のように、単なるエラーメッセージにするようにできないでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> 「ファイルがコピーできません・・・」というエラーメッセージが表示されるだけですが、 > Vistaでは、「・・・確認してから、操作を再実行してください」 例えば、 『エラーメッセージが表示された後に、「手動で当該ファイルを作成」してから、「再試行」を押してもコピーされない』 のでしょうか? コピーされるなら、 > 機能が追加されるのはかまわないと思いますが。 機能追加じゃないのかな・・・ #今までの「OK」ボタンの機能(コピーは取りやめ)は #新しいメッセージでは、「キャンセル」ボタンで置き換えられますよね・・・ #今までは「あきらめるしかなかった」のに、「再試行もできる」様になったのでしょうから。 個人的には、 > 設計ミスではないですか? とは思えませんが・・・ #尤も、『手動でファイルを作成して「再試行」してもコピーされない』なら #「設計ミス」でしょうけど・・・
その他の回答 (3)
- sha-girl
- ベストアンサー率52% (430/816)
SHFileOperation(FileCopyOperation)について少し補足です。 #3のサンプルコードをみればわかると思いますが SHFileOperationのpFromの終端はNULL文字が2文字必要です。 (複数ファイル指定のときNULL文字が区切り文字でもあるため、終端にはNULL文字が2文字必要になります。) もしそうしないとコピー元のファイルが見つからず、 「ファイルがコピーできません・・・」と表示されることがあります。 pFromの終端にNULL文字(vbだとChr(0)かな?)を2つ付けてください。 vbの例だと pFrom = "C:\Hoge.txt" & Chr(0) & Chr(0) といった記述のようです。 (もしそうしていなかったのなら旧環境では0で文字列初期化されていた為たまたま動いていただけです。vb5だとChr(0)を付けなくても動いていたようです。) またMSDNによると相対パスの指定は未定義となっているようです。 フルパスを書くようにしてください。 SHFileOperation VBで検索すると同じよう質問がたくさんありました。
お礼
回答ありがとうございます。
- sha-girl
- ベストアンサー率52% (430/816)
同じWindowsの名前がついているからといってメジャーバージョンの違う2つのOSに 100%互換を期待するべきではありません。他にもIMEに関する関数もVistaとXpでは 挙動が違うものがたくさんあります。 >「再試行」を押してもコピーされません。 それはコピー元のファイルが無いからでは?作ってもコピーされませんか? ためしにコードを書いてVistaで実行してみましたが ファイルを作成して再試行ボタンを押すと動きました。(下記VC++のコード) FileCopyOperationと書いてあるということはVBか何かで呼び出してますよね? 実際はshell32.dllの中にあるSHFileOperationA(Unicodeの場合はSHFileOperationW)が呼ばれています。 >設計ミスではないですか? これが設計ミスなのだとするとWindows2000に対するWindowsXpも設計ミスということになります。 2000とXpだって、WndProcの挙動が違ったりします。 OSのメジャーバージョンアップの過程ではWindowsに限らず起きる話です。 Vista対応は各社(各人)が苦しめられていると思いますが他のOSと比べれば Windowsの旧バージョンとの互換性は相当高い部類です。 (それがWindowsが普及している一つの理由ですし。) この件に限れば単にファイルの有無を前もってチェックして なければ共通のダイアログを出せば解決する話だと思います。 TCHAR path[1024]; TCHAR from[1024]; TCHAR to[1024]; GetModuleFileName( NULL , path , 1024 ); int nLast = 0; for(int i = lstrlen(path)-1 ; i >= 0 ; i-- ){ if (path[i] == _T('\\')){ nLast = i; // UNICODE前提 break; } } path[nLast] = _T('\0'); lstrcpy( from , path ); lstrcpy( to , path ); lstrcat( from , _T("\\a.txt") ); lstrcat( to , _T("\\b.txt") ); from[ lstrlen(from) + 1 ] = _T('\0'); to[ lstrlen(to) + 1 ] = _T('\0'); SHFILEOPSTRUCT fileop; ZeroMemory( &fileop , sizeof(SHFILEOPSTRUCT) ); fileop.pFrom = from; fileop.pTo = to; fileop.hwnd = NULL; fileop.fFlags = FOF_MULTIDESTFILES; fileop.wFunc = FO_COPY; fileop.fAnyOperationsAborted = FALSE; fileop.hNameMappings = NULL; fileop.lpszProgressTitle = _T("title"); SHFileOperation(&fileop );
お礼
回答ありがとうございます。 > それはコピー元のファイルが無いからでは?作ってもコピーされませんか? コピーされません。 > この件に限れば単にファイルの有無を前もってチェックして > なければ共通のダイアログを出せば解決する話だと思います。 承知しております。
- popesyu
- ベストアンサー率36% (1782/4883)
そりゃまぁAPIはDLLのバージョンに依存するわけですから、 OS環境が変われば(Shell32.DLLのバージョンも同様に変わるわけで)関数の仕様も変わります。 VistaのShell32.DLLに古いバージョンの方式で動作するような方式がわざわざ設けられているとは思えませんので、APIは環境依存するのでこれが仕様ですで諦めるしかないかと思います。 2000用のShell32.DLLを常に持ち歩くという手もあるかもしれませんが、Shell32.DLL の再頒布は許可されていないようですから、問題があるかもしれません。
お礼
回答ありがとうございます。 しかし、いままで「OK」ボタンだったのに、「再試行 / キャンセル」という二つのボタンになるというのは、設計ミスではないですか? 機能が追加されるのはかまわないと思いますが。
お礼
回答ありがとうございます。 > 『エラーメッセージが表示された後に、「手動で当該ファイルを作成」してから、「再試行」を押してもコピーされない』 「再試行」を押してもコピーされません。