トップ回答者
vc++ での media player 利用について

質問
-
下記の環境で Mediaplayer コンポーネントを利用した動画管理のプログラムを作成しています。
Visual Studio 2008 ( VC++, MFC )
上記プログラムで動画ファイル再生後、クローズした状態で、動画ファイルの入った
フォルダーを SHFileOperation()で、ゴミ箱に移動しようとすると、Windows7 でのみ、
フォルダーまたは動画ファイルがオープンれたままとなってしまう様で、
「フォルダーアクセスの許可」画面が表示される事があります。
→ SHFileOperation() ではなく、エクスプローラーのゴミ箱移動もできません。
(フォルダ毎ではなく、フォルダー内のファイル全て→フォルダの2段階に分けて
エクスプローラでゴミ箱移動を行うと、問題なくできます)
→ Windows XP, VISTA では上記現象は再現せず、ごみ箱に移動できます。
→ 上記プログラムを終了すると、ごみ箱移動は可能となります。
→ 動画再生時と、ごみ箱移動時(直前)は下記の処理を行っています。
①動画再生時
CWMPPlayer4::newMedia(LPCTSTR bstrURL) ← 動画ファイル名をフルパスで指定
CWMPPlayer4::GetCurrentPlaylist()
CWMPPlaylist::insertItem(long lIndex, LPDISPATCH pIWMPMedia)
CWMPPlayer4::SetCurrentPlaylist(LPDISPATCH newValue)
②ごみ箱移動時(直前)
CWMPPlayer4 ::close()
CWMPPlayer4::GetCurrentPlaylist()
CWMPPlaylist::clear() ← 上記プレイリストのクリア
この件について、回避策等ご存知の方がいらっしゃいましたら、ご教示願います。
- 編集済み ライト開発 2012年10月2日 6:21
回答
-
直接の回答ではありませんが、Windows Vista以降では、SHFileOperationに代わってIFileOperationが推薦されています。実際、SHFileOperationではうまく動作しなかったが、IFileOperationでは正常に動作したという例もありました。可能であれば、IFileOperationを使用されてみてはいかがでしょうか?
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク ライト開発 2012年10月27日 6:40
-
SHFileOperation や IFileOperation はエクスプローラーがやっていることと同等なので、エクスプローラーでできない状態なら実行できません。(たぶん、trapemiya さんの投稿はその部分を読み落としているのかもしれません)
ちなみに、実行しているプログラムのカレントディレクトリがその消せないフォルダーになっていたりしませんか?
どれかのプログラムがカレントディレクトリとしているフォルダーは消せませんので、勝手に切り替わること(たとえばファイルを開くダイアログ)があれば、消せなくなるのもうなずけます。- 回答としてマーク ライト開発 2012年10月27日 6:42
-
>(たぶん、trapemiya さんの投稿はその部分を読み落としているのかもしれません)
ご指摘ありがとうございます。Winows 7においてSHFileOperationでは不具合が発生する場合あるということで先走ってしまい、早合点してしまったようです。それに、Windows Vistaでは問題なく動作していると書かれていますね(^^;
エクスプローラでもフォルダを削除できず、しかし、フォルダ内のファイルを全て削除するとエクスプローラでフォルダを削除できるようになるということですので、何か隠しファイルでもできているのかなぁと思ったりもしますが、全く自信がありません。すみません。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク ライト開発 2012年10月27日 6:41
すべての返信
-
直接の回答ではありませんが、Windows Vista以降では、SHFileOperationに代わってIFileOperationが推薦されています。実際、SHFileOperationではうまく動作しなかったが、IFileOperationでは正常に動作したという例もありました。可能であれば、IFileOperationを使用されてみてはいかがでしょうか?
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク ライト開発 2012年10月27日 6:40
-
アドバイスありがとうございます。
戻り値はいい加減ですが、サンプルを参考に下記の様なプログラムで試してみたのですが、
結果は同じでした。
また、以下の現象より、media player が再生対象のフォルダを掴んだままになっている
様な気がしています。 → 関連する関数で手放せれば良いのですが、、
①一旦現象が再現すると、一度でも再生を行ったフォルダ全てが、プログラム終了まで
削除できなくなる。
②プログラム上で media player のオブジェクトを破棄した後は、削除できる
(プログラムの大幅な改修が必要になるので、できれば行いたくありません)
bool ****::MoveToTrashBox( const CString &i_strFileName, HWND i_hWnd) // HRESULT CTool::CopyItem(__in PCWSTR pszSrcItem, __in PCWSTR pszDest, PCWSTR pszNewName) { // // Initialize COM as STA. // HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; // // Create the IFileOperation interface // hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { // // Set the operation flags. Turn off all UI from being shown to the // user during the operation. This includes error, confirmation, // and progress dialogs. // hr = pfo->SetOperationFlags( FOF_SILENT | FOF_ALLOWUNDO | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMATION ); if (SUCCEEDED(hr)) { // // Create an IShellItem from the supplied source path. // IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(i_strFileName, NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { /* IShellItem *psiTo = NULL; if (NULL != pszDest) { // // Create an IShellItem from the supplied // destination path. // hr = SHCreateItemFromParsingName(pszDest, NULL, IID_PPV_ARGS(&psiTo)); } */ // if (SUCCEEDED(hr)) { // // Add the operation // hr = pfo->DeleteItem( psiFrom, NULL); // if (NULL != psiTo) // { // psiTo->Release(); // } } psiFrom->Release(); } if (SUCCEEDED(hr)) { // // Perform the operation to copy the file. // hr = pfo->PerformOperations(); } } // // Release the IFileOperation interface. // pfo->Release(); } CoUninitialize(); } // return hr; return true ; }
-
SHFileOperation や IFileOperation はエクスプローラーがやっていることと同等なので、エクスプローラーでできない状態なら実行できません。(たぶん、trapemiya さんの投稿はその部分を読み落としているのかもしれません)
ちなみに、実行しているプログラムのカレントディレクトリがその消せないフォルダーになっていたりしませんか?
どれかのプログラムがカレントディレクトリとしているフォルダーは消せませんので、勝手に切り替わること(たとえばファイルを開くダイアログ)があれば、消せなくなるのもうなずけます。- 回答としてマーク ライト開発 2012年10月27日 6:42
-
>(たぶん、trapemiya さんの投稿はその部分を読み落としているのかもしれません)
ご指摘ありがとうございます。Winows 7においてSHFileOperationでは不具合が発生する場合あるということで先走ってしまい、早合点してしまったようです。それに、Windows Vistaでは問題なく動作していると書かれていますね(^^;
エクスプローラでもフォルダを削除できず、しかし、フォルダ内のファイルを全て削除するとエクスプローラでフォルダを削除できるようになるということですので、何か隠しファイルでもできているのかなぁと思ったりもしますが、全く自信がありません。すみません。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
- 回答としてマーク ライト開発 2012年10月27日 6:41
-
現象が再現する際、フリーソフトの unlocker で該当フォルダーをモニタすると、やはり media player で再生したファイルがロック状態のままになっている事があり(再現性は100%ではありません)、同ソフトで lock を解除すると、その後は期待通りの動きをする事が確認できました。
そこで矛先を変えて、この unlocker と同等の機能を盛り込めないかと思ったのですが、このツールの様に現在ロックされているファイルのハンドルを取得して、lock 解除を行う方法についてご存知の方がいらっしゃれば、ご教示願います。
unlocker:
http://www.emptyloop.com/unlocker/
- 編集済み ライト開発 2012年10月27日 7:06
-
Unlocker の動作原理は知りませんが、デバッグの特権を与えなければ動かないはずです。
あなたが作るプログラムがどういったものかは知りませんが、ユーザーにそのような設定をさせないといけないソフトウェアを使いたいと思いますか?どちらかというと、本来の問題の解決に向けて追いかけるべきです。
それが、技術サポートに問い合わせないとわからないという状況であってもです。
(ロックの解放漏れという不具合かもしれませんが、本来、ロックを他者が解除するのはそのプログラムが動かなくなる原因になりかねません)- 編集済み AzuleanMVP, Moderator 2012年10月27日 10:57
- 回答としてマーク ライト開発 2012年10月27日 21:02
- 回答としてマークされていない ライト開発 2012年10月27日 21:04