虚拟化实例生命周期

提供程序应用程序维护一个或多个虚拟化实例。 每个虚拟化实例在其生命周期中经历四个阶段:

  1. 创造
  2. 启动
  3. 运行
  4. 关闭

请注意,关闭虚拟化实例后,提供程序无需重新创建它来重复使用它。 它可以直接重新启动它。

注意:本节显示了 ProjFS API 的示例。 每个示例旨在说明基本的 API 用法。 有关这些示例中未使用的选项的文档,请参阅 ProjFS API 参考

创建虚拟化根

在提供程序可以启动将项投影到本地文件系统的虚拟化实例之前,它必须创建虚拟化根。 虚拟化根目录是提供程序在其中投影目录和文件的树的目录。

若要创建虚拟化根目录,提供程序必须:

  1. 创建用作虚拟化根目录的目录。

    提供程序创建一个目录,以用作虚拟化根目录,例如 CreateDirectory

    HRESULT hr;
    const wchar_t* rootName = LR"(C:\virtRoot)";
    if (!CreateDirectoryW(rootName, nullptr))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        wprintf(L"Failed to create virtualization root (0x%08x)\n", hr);
        return;
    }
    
  2. 创建虚拟化实例 ID。

    每个虚拟化实例都有一个名为 虚拟化实例 ID的唯一 ID。 系统使用此值标识其内容关联的虚拟化实例。

    GUID instanceId;
    hr = CoCreateGuid(&instanceId);
    if (FAILED(hr))
    {
        wprintf(L"Failed to create instance ID (0x%08x)\n", hr);
        return;
    }
    
  3. 将新目录标记为虚拟化根目录。

    提供程序调用 PrjMarkDirectoryAsPlaceholder 将新目录标记为虚拟化根目录,并将其分配给虚拟化实例。

    hr = PrjMarkDirectoryAsPlaceholder(rootName,
                                       nullptr,
                                       nullptr,
                                       &instanceId);
    if (FAILED(hr))
    {
        wprintf(L"Failed to mark virtualization root (0x%08x)\n", hr);
        return;
    }
    

提供程序只需为每个虚拟化实例创建一次虚拟化根目录。 创建根后,可以重复启动和停止其关联的实例,而无需重新创建根。

启动虚拟化实例

创建虚拟化根后,提供程序必须启动虚拟化实例。 这向 ProjFS 发出信号,表明提供程序已准备好接收回调并提供数据。

若要启动虚拟化实例,提供程序必须:

  1. 设置回调表。

    ProjFS 通过调用提供程序实现的回调例程来与提供程序通信。 提供程序使用指向其回调例程的指针填充 PRJ_CALLBACKS 结构。

    PRJ_CALLBACKS callbackTable;
    
    // Supply required callbacks.
    callbackTable.StartDirectoryEnumerationCallback = MyStartEnumCallback;
    callbackTable.EndDirectoryEnumerationCallback = MyEndEnumCallback;
    callbackTable.GetDirectoryEnumerationCallback = MyGetEnumCallback;
    callbackTable.GetPlaceholderInfoCallback = MyGetPlaceholderInfoCallback;
    callbackTable.GetFileDataCallback = MyGetFileDataCallback;
    
    // The rest of the callbacks are optional.
    callbackTable.QueryFileNameCallback = nullptr;
    callbackTable.NotificationCallback = nullptr;
    callbackTable.CancelCommandCallback = nullptr;
    
  2. 启动实例。

    提供程序调用 PrjStartVirtualizing 来启动虚拟化实例。

    PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT instanceHandle;
    hr = PrjStartVirtualizing(rootName,
                              &callbackTable,
                              nullptr,
                              nullptr,
                              &instanceHandle);
    if (FAILED(hr))
    {
        wprintf(L"Failed to start the virtualization instance (0x%08x)\n", hr);
        return;
    }
    

    PrjStartVirtualizing's instanceHandle 参数返回虚拟化实例的句柄。 提供程序在调用其他 ProjFS API 时使用此句柄。

虚拟化实例运行时

调用 PrjStartVirtualizing 返回后,ProjFS 将调用提供程序的回调例程,以响应虚拟化实例中的文件系统作。 有关提供程序如何处理各种文件系统作的信息,请参阅以下部分:

关闭虚拟化实例

若要向 ProjFS 发出提供程序想要停止接收回调和提供数据的信号,提供程序必须停止虚拟化实例。 为此,提供程序调用 PrjStopVirtualizing,将句柄传递给从调用 PrjStartVirtualizing收到的虚拟化实例。

PrjStopVirtualizing(instanceHandle);

请注意,在调用返回之前,ProjFS 可能会继续调用提供程序的回调例程。