Compartir a través de


Secuencia de inicialización de subtipos de proyecto

El entorno construye un proyecto llamando a la implementación del generador de proyectos base de CreateProject. La construcción de un subtipo de proyecto se inicia cuando el entorno determina que la lista GUID de tipo de proyecto para la extensión de un archivo de proyecto no está vacía. La extensión de archivo de proyecto y el GUID del proyecto especifican si el proyecto es un tipo de proyecto de Visual Basic o Visual C#. Por ejemplo, la extensión .vbproj y {F184B08F-C81C-45F6-A57F-5ABD9991F28F} identifican un proyecto de Visual Basic.

Inicialización del entorno de subtipos de proyecto

En el procedimiento siguiente se detalla la secuencia de inicialización de un sistema de proyecto agregado por varios subtipos de proyecto.

  1. El entorno llama al proyecto CreateProjectbase y, mientras que el proyecto analiza su archivo de proyecto, detecta que la lista de GUID de tipo de proyecto agregado no nulles . El proyecto deja de crear directamente su proyecto.

  2. El proyecto llama QueryService al SVsCreateAggregateProject servicio para crear un subtipo de proyecto mediante la implementación del entorno del CreateAggregateProject método . Dentro de este método, el entorno realiza llamadas de función recursiva a las implementaciones de PreCreateForOuter, SetInnerProject y InitializeForOuter métodos mientras recorre la lista de GUID de tipo proyecto, empezando por el subtipo de proyecto más externo.

    A continuación se detallan los pasos de inicialización.

    1. La implementación del entorno del CreateAggregateProject método llama al HrCreateInnerProj método con la siguiente declaración de función:

      <CodeContentPlaceHolder>0

      Cuando se llama a esta función por primera vez, es decir, para el subtipo de proyecto más externo, los parámetros pOuter y se pasan como null y pOwner la función establece el subtipo IUnknown pOuterde proyecto más externo en .

    2. A continuación, el entorno llama a HrCreateInnerProj la función con el segundo GUID de tipo de proyecto en la lista. Este GUID corresponde al segundo subtipo de proyecto interno que avanza hacia el proyecto base en la secuencia de agregación.

    3. pOuter ahora apunta al IUnknown del subtipo de proyecto más externo y HrCreateInnerProj llama a la implementación de seguido de PreCreateForOuter una llamada a la implementación de SetInnerProject. En PreCreateForOuter el método se pasa el control IUnknown del subtipo de proyecto más externo, pOuter. El proyecto propiedad (subtipo de proyecto interno) debe crear aquí su objeto de proyecto agregado. En la implementación del SetInnerProject método, pase un puntero al del proyecto interno que se va a IUnknown agregar. Estos dos métodos crean el objeto de agregación y las implementaciones deben seguir las reglas de agregación COM para asegurarse de que un subtipo de proyecto no termina manteniendo un recuento de referencias a sí mismo.

    4. HrCreateInnerProj llama a la implementación de PreCreateForOuter. En este método, el subtipo del proyecto realiza su trabajo de inicialización. Por ejemplo, puede registrar eventos de solución en InitializeForOuter.

    5. HrCreateInnerProj se llama de forma recursiva hasta que se alcanza el último GUID (el proyecto base) de la lista. Para cada una de estas llamadas, los pasos, c a d, se repiten. pOuter apunta al subtipo IUnknown de proyecto más externo para cada nivel de agregación.

Ejemplo

En el ejemplo siguiente se detalla el proceso mediante programación en una representación aproximada del CreateAggregateProject método tal como lo implementa el entorno. El código es solo un ejemplo; no está pensado para compilarse y se quitó toda la comprobación de errores para mayor claridad.

HRESULT CreateAggregateProject
(
    LPCOLESTR lpstrGuids,
    LPCOLESTR pszFilename,
    LPCOLESTR pszLocation,
    LPCOLESTR pszName,
    VSCREATEPROJFLAGS grfCreateFlags,
    REFIID iidProject,
    void **ppvProject)
{
    HRESULT hr = NOERROR;
    CComPtr<IUnknown> srpunkProj;
    CComPtr<IVsAggregatableProject> srpAggProject;
    CComBSTR bstrGuids = lpstrGuids;
    BOOL fCanceled = FALSE;
    *ppvProject = NULL;

    HrCreateInnerProj(
         bstrGuids, NULL, NULL, pszFilename, pszLocation,
         pszName, grfCreateFlags, &srpunkProj, &fCanceled);
    srpunkProj->QueryInterface(
        IID_IVsAggregatableProject, (void **)&srpAggProject));
    srpAggProject->OnAggregationComplete();
    srpunkProj->QueryInterface(iidProject, ppvProject);
}

HRESULT HrCreateInnerProj
(
    WCHAR *pwszGuids,
    IUnknown *pOuter,
    IVsAggregatableProject *pOwner,
    LPCOLESTR pszFilename,
    LPCOLESTR pszLocation,
    LPCOLESTR pszName,
    VSCREATEPROJFLAGS grfCreateFlags,
    IUnknown **ppInner,
    BOOL *pfCanceled
)
{
    HRESULT hr = NOERROR;
    CComPtr<IUnknown> srpInner;
    CComPtr<IVsAggregatableProject> srpAggInner;
    CComPtr<IVsProjectFactory> srpProjectFactory;
    CComPtr<IVsAggregatableProjectFactory> srpAggPF;
    GUID guid = GUID_NULL;
    WCHAR *pwszNextGuids = wcschr(pwszGuids, L';');
    WCHAR wszText[_MAX_PATH+150] = L"";

    if (pwszNextGuids)
    {
        *pwszNextGuids++ = 0;
    }

    CLSIDFromString(pwszGuids, &guid);
    GetProjectTypeMgr()->HrGetProjectFactoryOfGuid(
        guid, &srpProjectFactory);
    srpProjectFactory->QueryInterface(
        IID_IVsAggregatableProjectFactory,
        (void **)&srpAggPF);
    srpAggPF->PreCreateForOuter(pOuter, &srpInner);
    srpInner->QueryInterface(
        IID_IVsAggregatableProject, (void **)&srpAggInner);

    if (pOwner)
    {
        IfFailGo(pOwner->SetInnerProject(srpInner));
    }

    if (pwszNextGuids)
    {
        CComPtr<IUnknown> srpNextInner;
        HrCreateInnerProj(
            pwszNextGuids, pOuter ? pOuter : srpInner,
            srpAggInner, pszFilename, pszLocation, pszName,
            grfCreateFlags, &srpNextInner, pfCanceled);
    }

    return srpAggInner->InitializeForOuter(
        pszFilename, pszLocation, pszName, grfCreateFlags,
        IID_IUnknown, (void **)ppInner, pfCanceled);
}