Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Goed geschreven onderdelen verstoren de omgeving van de hostingtoepassing niet, noch lekken ze activeringscontexten. Goed geschreven onderdelen voeren hun eigen contextbeheer uit in plaats van te vertrouwen op de omgeving van de hostingtoepassing.
De auteur van het gehoste onderdeel heeft de beste positie om precies te weten welke andere assembly's het onderdeel nodig heeft. Het vertrouwen op de hosttoepassing om de juiste omgeving voor uw gehoste component te bieden, is waarschijnlijk een bron van fouten. Maak in plaats daarvan een manifest voor uw gehoste onderdeel dat alle afhankelijkheden opgeeft en compileer vervolgens met behulp van ISOLATION_AWARE_ENABLED. Dit zorgt ervoor dat externe aanroepen van uw onderdeel worden geïsoleerd en de juiste versies gebruiken. Omdat de activeringscontext die ISOLATION_AWARE_ENABLED gebruikt per DLL is, is het veilig om in meerdere DLL's te gebruiken, elk met hun eigen manifest dat afhankelijkheden aanroept.
Als het niet mogelijk is om te compileren met ISOLATION_AWARE_ENABLED, gebruik dan een oplossing zoals die gepresenteerd in Het gebruiken van callbacks van gehoste componenten.
Activeer uw eigen activeringscontext op alle toegangspunten die de hostingtoepassing kan aanroepen om ervoor te zorgen dat uw gehoste onderdeel volledig wordt uitgevoerd met de juiste activeringscontext. U kunt een C++-helperobject gebruiken om het wijzigen van alle toegangspunten te vergemakkelijken. U kunt bijvoorbeeld een C++-klasse gebruiken, zoals de volgende:
#include <windows.h>
class CActivationContext
{
HANDLE m_hActivationContext;
public:
CActivationContext() : m_hActivationContext(INVALID_HANDLE_VALUE)
{
}
VOID Set(HANDLE hActCtx)
{
if (hActCtx != INVALID_HANDLE_VALUE)
AddRefActCtx(hActCtx);
if (m_hActivationContext != INVALID_HANDLE_VALUE)
ReleaseActCtx(m_hActivationContext);
m_hActivationContext = hActCtx;
}
~CActivationContext()
{
if (m_hActivationContext != INVALID_HANDLE_VALUE)
ReleaseActCtx(m_hActivationContext);
}
BOOL Activate(ULONG_PTR &ulpCookie)
{
return ActivateActCtx(m_hActivationContext, &ulpCookie);
}
BOOL Deactivate(ULONG_PTR ulpCookie)
{
return DeactivateActCtx(0, ulpCookie);
}
};
class CActCtxActivator
{
CActivationContext &m_ActCtx;
ULONG_PTR m_Cookie;
bool m_fActivated;
public:
CActCtxActivator(CActivationContext& src, bool fActivate = true)
: m_ActCtx(src), m_Cookie(0), m_fActivated(false)
{
if (fActivate) {
if (src.Activate(m_Cookie))
m_fActivated = true;
}
}
~CActCtxActivator()
{
if (m_fActivated) {
m_ActCtx.Deactivate(m_Cookie);
m_fActivated = false;
}
}
};
Dit kan vervolgens worden gebruikt in uw onderdeel, met behulp van een globale variabele om de activeringscontext op te slaan die op elk toegangspunt moet worden geactiveerd. Op deze manier kunt u uw onderdeel isoleren van uw hostingtoepassing.
CActivationContext s_GlobalContext;
void MyExportedEntrypoint(void)
{
CActCtxActivator ScopedContext(s_GlobalContext);
// Do whatever work here
// Destructor automatically deactivates the context
}
void MyInitializerFunction()
{
HANDLE hActCtx;
ACTCTX actctx = {sizeof(actctx)};
hActCtx = CreateActCtx(&actctx);
s_GlobalContext.Set(hActCtx);
ReleaseActCtx(hActCtx);
// The static destructor for s_GlobalContext destroys the
// activation context on component unload.
}