none
実行ファイルと同じフォルダにあるファイルを上書きできない RRS feed

  • 質問

  • OS:Windows7

    開発環境:VS2008 SP1


    SHFileOperationを使用して、実行ファイルと同じフォルダにあるファイルを上書きしようとしています。

    AのフォルダにBのフォルダを上書きして、iniファイルを更新させようとしているのですが、

    Aのフォルダでhoge.exeを実行したままの状態で上書きを行うと、

    「既に存在するファイルを作成することはできません。 」となり、コピーに失敗してしまいます。

    OSがXPだったり、アプリを落とした状態や、上書き確認メッセージを表示すれば成功するのですが、

    Windows7でアプリを起動したまま、メッセージを出さずに上書きさせようとすると、上記のエラーになり、失敗してしまいます。

    回避する方法をご存じないでしょうか?

     

    実行中のアプリのフォルダ(A)

    hoge.exe

    hoge.ini

     

    コピーしたいファイルの入ったフォルダ(B)

    hoge.ini

     

    ソースコード

     

    	LPCTSTR lpszOldPath = "c:\\コピーしたいファイルの入ったフォルダ";
    	LPCTSTR lpszNewPath = "c:\\実行中のアプリのフォルダ";
    
    	int				iRet;
    	int				iLen = 0;
    	char			cOldPath[MAX_PATH];
    	char			cNewPath[MAX_PATH];
    	SHFILEOPSTRUCT	stSHFileOp;
    
    	// メモリクリア
    	::ZeroMemory( cOldPath, MAX_PATH );
    	::ZeroMemory( cNewPath, MAX_PATH );
    	ZeroMemory( &stSHFileOp, sizeof(SHFILEOPSTRUCT) );
    
    	iLen = (int)strlen( lpszOldPath );
    	if( MAX_PATH <= iLen )
    	{
    		iLen = MAX_PATH;
    	}
    	::CopyMemory( cOldPath, lpszOldPath, iLen );
    
    	iLen = (int)strlen( lpszNewPath );
    	if( MAX_PATH <= iLen )
    	{
    		iLen = MAX_PATH;
    	}
    	::CopyMemory( cNewPath, lpszNewPath, iLen );
    
    
    	stSHFileOp.hwnd					= NULL;
    	stSHFileOp.wFunc				= iOperation;
    	stSHFileOp.pFrom				= cOldPath; 
    	stSHFileOp.pTo					= cNewPath;
    	stSHFileOp.fFlags				= FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMMKDIR;
    	stSHFileOp.fAnyOperationsAborted= FALSE;
    	stSHFileOp.hNameMappings		= NULL;
    	stSHFileOp.lpszProgressTitle	= NULL;
    
    	iRet = SHFileOperation( &stSHFileOp );
    
    

     


    2011年1月5日 3:56

回答

  • フォルダーを上書きするのではなくて、ファイルをコピーすればいいのではないでしょうか。
    具体的には、lpszOldPath に "\\*.*" をくっつけて、fFlags に FOF_FILESONLY を追加すれば動作します。

    個人的には、char/WCHAR/_TCHAR の扱いがごちゃごちゃになっていたり、
    文字列バッファーの境界近くになると変な動きをしそうな点が気になりました。
    (pFrom と pTo は2個のヌル文字で終わらないといけないですよね。FOF_MULTIDESTFILES も指定しているし。)
    • 回答としてマーク kou7 2011年1月5日 6:41
    2011年1月5日 5:12

すべての返信

  • フォルダーを上書きするのではなくて、ファイルをコピーすればいいのではないでしょうか。
    具体的には、lpszOldPath に "\\*.*" をくっつけて、fFlags に FOF_FILESONLY を追加すれば動作します。

    個人的には、char/WCHAR/_TCHAR の扱いがごちゃごちゃになっていたり、
    文字列バッファーの境界近くになると変な動きをしそうな点が気になりました。
    (pFrom と pTo は2個のヌル文字で終わらないといけないですよね。FOF_MULTIDESTFILES も指定しているし。)
    • 回答としてマーク kou7 2011年1月5日 6:41
    2011年1月5日 5:12
  • 素早い回答ありがとうございます。

    lpszOldPathに "\\*" を付加する事で
    コピー元のフォルダの中身(含むフォルダ)をコピーすることができました。
    ありがとうございました。

    >個人的には、char/WCHAR/_TCHAR の扱いがごちゃごちゃになっていたり、
    指摘ありがとうございます。
    確かに、LPCTSTRを使用するなら_TCHARにすべきですね。
    修正します。

    >文字列バッファーの境界近くになると変な動きをしそうな点が気になりました。
    今回はMAX_PATHまで行かない仕様なのですが、
    こちらも追加しておきます。

    2011年1月5日 6:41