Winapi COM:OUT OF进程对象';执行上下文

Winapi COM:OUT OF进程对象';执行上下文,winapi,visual-c++,com,Winapi,Visual C++,Com,在阅读有关的文章时,我遇到了关于标志CLSCTX\u LOCAL\u服务器的声明 如果标志包括CLSCTX_LOCAL_SERVER,则 如果使用该类的LocalService键,则使用在该键下找到的服务 存在。如果未指定服务,但在该服务下指定了EXE 同一个键,使用与该EXE关联的类代码。班级 代码(在任何一种情况下)都将在服务器上的单独服务进程中运行 与呼叫方的计算机相同 这是否意味着对于以下代码,FileDialog对象的执行上下文将位于单独的进程中?是否有那么简单,即只需指定 CLSCT

在阅读有关的文章时,我遇到了关于标志
CLSCTX\u LOCAL\u服务器的声明

如果标志包括CLSCTX_LOCAL_SERVER,则 如果使用该类的LocalService键,则使用在该键下找到的服务 存在。如果未指定服务,但在该服务下指定了EXE 同一个键,使用与该EXE关联的类代码。班级 代码(在任何一种情况下)都将在服务器上的单独服务进程中运行 与呼叫方的计算机相同

这是否意味着对于以下代码,FileDialog对象的执行上下文将位于单独的进程中?是否有那么简单,即只需指定
CLSCTX\u LOCAL\u服务器
不需要更多吗?如果是这样,我如何识别/验证这个单独的流程是否确实在运行

#include <windows.h>
#include <shobjidl.h> 

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED |
        COINIT_DISABLE_OLE1DDE);
    if (SUCCEEDED(hr))
    {
        IFileOpenDialog *pFileOpen;

        // Create the FileOpenDialog object.
        hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_LOCAL_SERVER,
            IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

        if (SUCCEEDED(hr))
        {
            // Show the Open dialog box.
            hr = pFileOpen->Show(NULL);

            // Get the file name from the dialog box.
            if (SUCCEEDED(hr))
            {
                IShellItem *pItem;
                hr = pFileOpen->GetResult(&pItem);
                if (SUCCEEDED(hr))
                {
                    PWSTR pszFilePath;
                    hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

                    // Display the file name to the user.
                    if (SUCCEEDED(hr))
                    {
                        MessageBoxW(NULL, pszFilePath,  L"File Path", MB_OK);
                        CoTaskMemFree(pszFilePath);
                    }
                    pItem->Release();
                }
            }
            pFileOpen->Release();
        }
        CoUninitialize();
    }
    return 0;
}
#包括
#包括
int WINAPI wWinMain(HINSTANCE HINSTANCE、HINSTANCE、PWSTR pCmdLine、int nCmdShow)
{
HRESULT hr=CoInitializeX(空,Conit_APARTMENTTHREADED|
Conit_禁用_OLE1DDE);
如果(成功(hr))
{
IFileOpenDialog*pFileOpen;
//创建FileOpenDialog对象。
hr=CoCreateInstance(CLSID\u文件打开对话框,空,CLSCTX\u本地\u服务器,
IID_IFileOpenDialog,重新解释(和PFILEOpend));
如果(成功(hr))
{
//显示“打开”对话框。
hr=pFileOpen->Show(空);
//从对话框中获取文件名。
如果(成功(hr))
{
伊舍利姆*pItem;
hr=pFileOpen->GetResult(&pItem);
如果(成功(hr))
{
PWSTR-pszFilePath;
hr=pItem->GetDisplayName(SIGDN_FILESYSPATH和pszFilePath);
//向用户显示文件名。
如果(成功(hr))
{
MessageBoxW(NULL,pszFilePath,L“文件路径”,MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
coninitialize();
}
返回0;
}

从理论上讲,如果FileDialog注册表项指定了有效的.exe(或服务名称),它就可以工作。但事实并非如此,HKCR\CLSID\{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}只包含指向dll的InProcServer32,因此它只在进程中工作(在这种情况下忽略CLSCTX_本地_服务器)。请注意,支持进程外COM通信并不是一个既定目标。这取决于COM对象的编写方式,它必须声明代理/存根(或使用自动化类型)等。通常不可能对显示嵌入式UI的任何组件进行进程外激活。过去是这样的,当时微软仍然认为OLE很有用。但奥立已经死了,这是理所当然的。即使在那个时候,这些shell对话框也是严格地进行中的。