Поделиться через


Загрузка графа из внешнего процесса

[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]

GraphEdit может загружать граф фильтра, созданный внешним процессом. С помощью этой функции вы можете точно увидеть, какой граф фильтров создается приложением, с минимальным объемом дополнительного кода в приложении.

Примечание

Для этой функции требуется Windows 2000, Windows XP или более поздней версии.

 

Примечание

Начиная с Windows Vista, необходимо зарегистрировать proppage.dll, чтобы включить эту функцию. Proppage.dll входит в windows SDK.

 

Приложение должно зарегистрировать экземпляр графа фильтра в таблице выполняющихся объектов (ROT). ROT — это глобально доступная таблица поиска, которая отслеживает запущенные объекты. Объекты регистрируются в ROT по моникеру. Чтобы подключиться к графу, GraphEdit ищет в rot моникеры, отображаемое имя которых соответствует определенному формату:

!FilterGraph X pid Y

где X — шестнадцатеричный адрес диспетчера графов фильтров, а Y — идентификатор процесса, также в шестнадцатеричном формате.

При первом создании графа фильтра приложением вызовите следующую функцию:

HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{
    IMoniker * pMoniker = NULL;
    IRunningObjectTable *pROT = NULL;

    if (FAILED(GetRunningObjectTable(0, &pROT))) 
    {
        return E_FAIL;
    }
    
    const size_t STRING_LENGTH = 256;

    WCHAR wsz[STRING_LENGTH];
 
   StringCchPrintfW(
        wsz, STRING_LENGTH, 
        L"FilterGraph %08x pid %08x", 
        (DWORD_PTR)pUnkGraph, 
        GetCurrentProcessId()
        );
    
    HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) 
    {
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,
            pMoniker, pdwRegister);
        pMoniker->Release();
    }
    pROT->Release();
    
    return hr;
}

Эта функция создает моникер и новую запись ROT для графа фильтра. Первый параметр — это указатель на граф фильтра. Второй параметр получает значение, определяющее новую запись ROT. Прежде чем приложение выпустит граф фильтра, вызовите следующую функцию, чтобы удалить запись ROT. Параметр pdwRegister — это идентификатор, возвращаемый функцией AddToRot.

void RemoveFromRot(DWORD pdwRegister)
{
    IRunningObjectTable *pROT;
    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
}

В следующем примере кода показано, как вызывать эти функции. В этом примере код, который добавляет и удаляет записи ROT, условно компилируется, поэтому он включается только в отладочные сборки.

IGraphBuilder *pGraph;
DWORD dwRegister;
    
// Create the filter graph manager.
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                        IID_IGraphBuilder, (void **)&pGraph);
#ifdef _DEBUG
hr = AddToRot(pGraph, &dwRegister);
#endif

// Rest of the application (not shown).

#ifdef _DEBUG
RemoveFromRot(dwRegister);
#endif
pGraph->Release();

Чтобы просмотреть граф фильтра в GraphEdit, запустите приложение и GraphEdit одновременно. В меню GraphEdit File (Изменить файл ) щелкните Подключиться к удаленному графу... В диалоговом окне Подключение к Graph выберите идентификатор процесса (pid) приложения и нажмите кнопку ОК. GraphEdit загружает граф фильтра и отображает его. Не используйте другие функции GraphEdit на этом графе— это может привести к непредвиденным результатам. Например, не добавляйте и не удаляйте фильтры, не останавливайте и не запускайте граф. Закройте GraphEdit перед выходом из приложения.

Примечание

При выходе приложение может столкнуться с различными утверждениями. На них можно не обращать внимания.

 

На следующем рисунке показано диалоговое окно Подключение к графу .

подключение к графу

Когда GraphEdit загружает граф, он выполняется в контексте целевого приложения. Таким образом, GraphEdit может блокироваться, так как ожидает поток. Например, это может произойти при пошаговом выполнении кода в отладчике.

Эту функцию следует использовать только в отладочных сборках приложения, а не в розничных сборках, так как она позволяет другим приложениям просматривать граф фильтров и управлять им.

Подключение к удаленному графу из командной строки

GraphEdit поддерживает параметр командной строки для автоматической загрузки удаленного графа при запуске. Синтаксис:

GraphEdt -a moniker

где моникер — это моникер, созданный с помощью функции AddToRot, описанной ранее.

Имитация построения графа с помощью GraphEdit