我可以使用文件初始化 IThumbnailProvider 对象吗?

Can I Initialize a IThumbnailProvider Object with a File?

我正在编写实现 IInitializeWithFile 的缩略图提供程序,但是传递给初始化方法的文件路径无效。

我不能使用 IInitializeWithStream 的原因是我需要 return 正确缩略图的文件路径。

IFACEMETHODIMP RecipeThumbnailProvider::Initialize(LPCWSTR FilePath, DWORD Mode){
    std::wofstream *FileStream1 = new std::wofstream("D:\test1.txt");

    if(!PathFileExistsW(FilePath)){//check if the passed path is valid
        (*FileStream1)<< L"path invalid";
    }else{
        (*FileStream1)<<L"path valid" << FilePath;
    }
    (*FileStream1).close();

    // A handler instance should be initialized only once in its lifetime. 
    HRESULT hr = ERROR_ALREADY_INITIALIZED;
    if (m_pStream == NULL)
    {
        hr = SHCreateStreamOnFileW(FilePath, Mode, &m_pStream);//get IStream from file path
    }
    return hr;
}

从 Windows Vista 开始,您似乎只能使用 IInitializeWithStream

我在这里做了一些广泛的测试(参见 this pull request and this pull request。测试表明 Initialize 方法 不会被调用 除非服务器实现 IInitializeWithStream.

最新的 MSDN 文档位于:

https://docs.microsoft.com/en-us/windows/win32/api/thumbcache/nn-thumbcache-ithumbnailprovider

也好像是在暗示这个:

The Shell calls IInitializeWithStream::Initialize with the stream of the item, and IInitializeWithStream is the only initialization interface used when IThumbnailProvider instances are loaded out-of-proc (for isolation purposes). This is the primary code path for Windows for all IThumbnailCache code paths.

It is possible for a thumbnail implementation to be initialized with IInitializeWithItem or IInitializeWithFile when the handler is request by a 3rd party without using the IThumbnailCache API, but this is uncommon. If you implement IInitializeWithItem, the Shell calls IInitializeWithItem::Initialize with the IShellItem representation of the item. If you implement IInitializeWithFile, the Shell calls IInitializeWithFile::Initialize with the path of the file.

我相信由于 here 提到的安全问题,Microsoft 可能已确保 shell 将仅使用 IInitializeWithStream.

我仍在调查是否有 一些 迂回方式从 IStream 获取路径 - 到目前为止我只能获取显示名称。但是,如果作为 IStream 的对象还实现了一些其他接口,则可能会查询它的路径,如果我发现了一种方法,我会更新这个答案。