シリーズもの一覧
1/4 https://qiita.com/macchan/items/30d81c4cb66a52fe4b0b
2/4 https://qiita.com/macchan/items/282db3e735ed0ad4bed8
3/4 https://qiita.com/macchan/items/19a06f30e8f3c553d4cb
4/4 https://qiita.com/macchan/items/9853a6d7b4e01ad4dc8d
SHFileOperationA, SHFileOperationW を見ると
This function has been replaced in Windows Vista by IFileOperation.
と書いてあります。訳すと「Windows Vista で IFileOperation に置き換えられた」で、つまり SHFileOperation は「いつ使えなくなるかわからない」ということになります。
Windows Vistaは(Wikipediaで調べました)2006年ですからもうかれこれ20年前になります。
筆者の環境はVisualStudio 2019で、SHFileOperation はまだ使えていますが、モノは試しに書いてみましょう。
IFileOperation インターフェースのプログラムサンプルは以下にあります。
かなり長くなりました。<atlcomcli.h> を includeすると スマートポインタ CComptr が使えて少しはマシになりますが、それでも「たかがディレクトリを削除するのにCOMインターフェースを使うのか」というのが素直な感想です。あ、これも読み取り専用属性を無視して削除します。いやはや。
#include <iostream>
#include <windows.h>
#include <shobjidl_core.h>
#include <locale>
int main()
{
setlocale(LC_ALL, "Japanese");
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
IShellItem* psiTarget = NULL;
if(FAILED(hr)) {
std::cout << "COM初期化失敗" << std::endl;
return -1;
}
// インターフェース インスタンス生成
IFileOperation* pFileOp;
hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pFileOp));
if (FAILED(hr)) {
std::cout << "IFileOperation インターフェース失敗" << std::endl;
goto End01;
}
hr = pFileOp->SetOperationFlags(FOF_NO_UI);
if (FAILED(hr))
{
std::cout << "SetOperationFlags 失敗" << std::endl;
goto End01;
}
hr = SHCreateItemFromParsingName(L"D:\\Work\\Dir", NULL, IID_PPV_ARGS(&psiTarget));
if (FAILED(hr))
{
std::cout << "SHCreateItemFromParsingName 失敗" << std::endl;
goto End02;
}
// 準備(宣言)
hr = pFileOp->DeleteItem(psiTarget, NULL);
if (FAILED(hr))
{
std::cout << "DeleteItem 失敗" << std::endl;
goto End03;
}
// 削除実行
hr = pFileOp->PerformOperations();
if (FAILED(hr))
{
std::cout << "PerformOperations 失敗" << std::endl;
goto End03;
}
std::cout << "Delete 成功" << std::endl;
End03:
if (psiTarget) {
psiTarget->Release();
psiTarget = NULL;
}
End02:
if (pFileOp) {
pFileOp->Release();
pFileOp = NULL;
}
End01:
// COMの後始末
CoUninitialize();
return 0;
}