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


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

[Функция, связанная с этой страницей, 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 входит в пакет SDK для Windows.

 

Приложение должно зарегистрировать экземпляр графа фильтра в таблице запущенных объектов (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 щелкните "Подключиться к удаленному графу...". В диалоговом окне "Подключение к графу" выберите идентификатор процесса (pid) вашего приложения и нажмите "ОК". GraphEdit загружает граф фильтра и отображает его. Не используйте другие функции GraphEdit на этом графе. Это может привести к непредвиденным результатам. Например, не добавляйте или не удаляйте фильтры или остановите и запустите граф. Закройте GraphEdit перед выходом из приложения.

Заметка

Приложение может ударить по различным утверждениям при выходе. Эти действия можно игнорировать.

 

Следующая иллюстрация показывает диалоговое окно Подключение к графу.

подключиться к графу

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

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

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

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

GraphEdt -a moniker

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

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