调用IPersistFile::Save后,如何等待保存完成?

调用IPersistFile::Save后,如何等待保存完成?

问题描述:

C++调用COM组件创建快捷方式。
创建完成后,马上要把创建好的.lnk文件复制到另一个位置,结果失败。
但是在创建完成后Sleep一段时间,就成功了。
推测是IPersistFile还没来得及写入文件。
我应该如何得知文件已经保存完成?

大致代码如下:

bool create_succ = false;

CoInitialize(NULL);
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkA, (void**)&pShellLink);
if (SUCCEEDED(hres))
{
    pShellLink->SetPath(target_path);
    IPersistFile *pPersistFile;
    hres = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
    if (SUCCEEDED(hres))
    {
        hres = pPersistFile->Save(link_file, TRUE);
        if (SUCCEEDED(hres))
        {
            create_succ = true;
        }
        pPersistFile->Release();
    }
    pShellLink->Release();
}
CoUninitialize();

//  Sleep(1000);    //  加上这句就能成功

if (create_succ)
{
    CopyFile(link_file, dest);
}

之前没怎么用过COM,望知道的指点一下,多谢~

已解决。最后证明不是COM和IPersistFile的问题。

刚刚创建的小于4KB(簇大小)的文件,立即使用会产生问题。不光是IPersistFile::Save(),就连CopyFile、CreateFile创建的文件,如果小于4KB,也有这个问题。需要补全才能用。另外,如果在可移动磁盘内创建小文件不补全,驱动器又在短时间内请求弹出的话,还会弹出失败。

补全流程:
1. 读取IPersistFile创建的lnk文件至内存。
2. 如果大小小于4KB,在后面用空白数据填充至4KB。
3. 新建一个文件,把填充后的lnk文件内容全部写入,关闭。

在原文件后面附加数据补全不行,必须新建文件!

Windows这种缓存文件的行为,MSDN里面好像也没说过,反正我没看到。这里真想吐槽一下。。。微软的东西坑实在是太多了。

调用pPersistFile->SaveCompleted看看