获取端口

端口表示与运行进程的计算机的连接。 该计算机可以是本地计算机或远程计算机(可能正在运行基于 Windows 的非操作系统);有关详细信息,请参阅 端口

端口由 IDebugPort2 接口表示。 它用于获取有关端口连接到的计算机上运行的进程的信息。

调试引擎需要访问端口才能向端口注册程序节点,并满足进程信息请求。 例如,如果调试引擎实现 IDebugProgramProvider2 接口,则 GetProviderProcessData 方法的实现可能会请求端口获取返回所需的进程信息。

Visual Studio 向调试引擎提供所需的端口,并从端口供应商获取此端口。 如果程序已附加到(无论是从调试器内部还是由于引发异常而引发异常),则会触发实时 [JIT] 对话框),则用户会选择传输(端口供应商的另一个名称)才能使用。 否则,如果用户从调试器中启动程序,则项目系统指定要使用的端口供应商。 在任一事件中,Visual Studio 实例化由 IDebugPortSupplier2 接口表示的端口供应商,并通过使用 IDebugPortRequest2 接口调用 AddPort 来请求新端口。 然后,此端口以一种或另一种形式传递到调试引擎。

示例

此代码片段演示如何使用提供给 LaunchSuspended 的端口在 ResumeProcess注册程序节点。 为了清楚起见,省略了不直接与此概念相关的参数。

注意

此示例使用端口启动和恢复进程,并假定 IDebugPortEx2 接口在端口上实现。 这绝不是执行这些任务的唯一方法,除了为它提供程序的 IDebugProgramNode2 之外,端口甚至可能不涉及。

// This is an IDebugEngineLaunch2 method.
HRESULT CDebugEngine::LaunchSuspended(/* omitted parameters */,
                                      IDebugPort2 *pPort,
                                      /* omitted parameters */,
                                      IDebugProcess2**ppDebugProcess)
{
    // do stuff here to set up for a launch (such as handling the other parameters)
    ...

    // Now get the IPortNotify2 interface so we can register a program node
    // in CDebugEngine::ResumeProcess.
    CComPtr<IDebugDefaultPort2> spDefaultPort;
    HRESULT hr = pPort->QueryInterface(&spDefaultPort);
    if (SUCCEEDED(hr))
    {
        CComPtr<IDebugPortNotify2> spPortNotify;
        hr = spDefaultPort->GetPortNotify(&spPortNotify);
        if (SUCCEEDED(hr))
        {
            // Remember the port notify so we can use it in ResumeProcess.
            m_spPortNotify = spPortNotify;

            // Now launch the process in a suspended state and return the
            // IDebugProcess2 interface
            CComPtr<IDebugPortEx2> spPortEx;
            hr = pPort->QueryInterface(&spPortEx);
            if (SUCCEEDED(hr))
            {
                // pass on the parameters we were given (omitted here)
                hr = spPortEx->LaunchSuspended(/* omitted parameters */,ppDebugProcess)
            }
        }
    }
    return(hr);
}

HRESULT CDebugEngine::ResumeProcess(IDebugProcess2 *pDebugProcess)
{
    // Make a program node for this process
    HRESULT hr;
    CComPtr<IDebugProgramNode2> spProgramNode;
    hr = this->GetProgramNodeForProcess(pProcess, &spProgramNode);
    if (SUCCEEDED(hr))
    {
        hr = m_spPortNotify->AddProgramNode(spProgramNode);
        if (SUCCEEDED(hr))
        {
            // resume execution of the process using the port given to us earlier.
            // (Querying for the IDebugPortEx2 interface is valid here since
            // that's how we got the IDebugPortNotify2 interface in the first place.)
            CComPtr<IDebugPortEx2> spPortEx;
            hr = m_spPortNotify->QueryInterface(&spPortEx);
            if (SUCCEEDED(hr))
            {
                hr = spPortEx->ResumeProcess(pDebugProcess);
            }
        }
    }
    return(hr);
}