i have my own scripting engine for a long time - but now i change to jscript engine. its not easy to handle all the interfaces within scripts. thats why very often circular references occur. for the first time you should load jscript by CoCreateInstance to enshure that jscript isnt unexpected unloaded. if you set any interfaces to the scripting engine SetScriptSite or other notification functions you should use zombie-interfaces. zombie means delagate all calls to the owner object if exist.
i.e:
class iZombieScriptSite : public IActiveScriptSite, public IDispatch
{
public:
virtual HRESULT __stdcall QueryInterface(REFIID riid,void** ppv);
virtual unsigned long __stdcall AddRef();
virtual unsigned long __stdcall Release();
public:
virtual HRESULT __stdcall GetLCID(LCID *plcid)
{ return _delegate?_delegate->GetLCID(plcid):E_FAIL; }
virtual HRESULT __stdcall GetItemInfo(LPCOLESTR pstrName,DWORD dwReturnMask,IUnknown **ppiunkItem,ITypeInfo **ppti)
{ return _delegate?_delegate->GetItemInfo(pstrName,dwReturnMask,ppiunkItem,ppti):E_FAIL; }
virtual HRESULT __stdcall GetDocVersionString(BSTR *pbstrVersion)
{ return _delegate?_delegate->GetDocVersionString(pbstrVersion):E_FAIL; }
virtual HRESULT __stdcall OnScriptTerminate(const VARIANT *pvarResult,const EXCEPINFO *pexcepinfo)
{ return _delegate?_delegate->OnScriptTerminate(pvarResult,pexcepinfo):E_FAIL; }
virtual HRESULT __stdcall OnStateChange(SCRIPTSTATE ssScriptState)
{ return _delegate?_delegate->OnStateChange(ssScriptState):E_FAIL; }
virtual HRESULT __stdcall OnScriptError(IActiveScriptError *pscripterror)
{ return _delegate?_delegate->OnScriptError(pscripterror):E_FAIL; }
virtual HRESULT __stdcall OnEnterScript()
{ return _delegate?_delegate->OnEnterScript():E_FAIL; }
virtual HRESULT __stdcall OnLeaveScript()
{ return _delegate?_delegate->OnLeaveScript():E_FAIL; }
public:
virtual HRESULT __stdcall GetTypeInfoCount(UINT *pctinfo)
{ return _dispatch?_dispatch->GetTypeInfoCount(pctinfo):E_FAIL; }
virtual HRESULT __stdcall GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
{ return _dispatch?_dispatch->GetTypeInfo(iTInfo,lcid,ppTInfo):E_FAIL; }
virtual HRESULT __stdcall GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
{ return _dispatch?_dispatch->GetIDsOfNames(riid,rgszNames,cNames,lcid,rgDispId):E_FAIL; }
virtual HRESULT __stdcall Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{ return _dispatch?_dispatch->Invoke(dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr):E_FAIL; }
public:
virtual HRESULT __stdcall GetDispID(BSTR bstrName,DWORD grfdex,DISPID *pid)
{ return _dispatch?_dispatch->GetDispID(bstrName,grfdex,pid):E_FAIL; }
virtual HRESULT __stdcall InvokeEx(DISPID id,LCID lcid,WORD wFlags,DISPPARAMS *pdp,VARIANT *pvarRes,EXCEPINFO *pei,IServiceProvider *pspCaller)
{ return _dispatch?_dispatch->InvokeEx(id,lcid,wFlags,pdp,pvarRes,pei,pspCaller):E_FAIL; }
virtual HRESULT __stdcall DeleteMemberByName(BSTR bstrName,DWORD grfdex)
{ return _dispatch?_dispatch->DeleteMemberByName(bstrName,grfdex):E_FAIL; }
virtual HRESULT __stdcall DeleteMemberByDispID(DISPID id)
{ return _dispatch?_dispatch->DeleteMemberByDispID(id):E_FAIL; }
virtual HRESULT __stdcall GetMemberProperties(DISPID id,DWORD grfdexFetch,DWORD *pgrfdex)
{ return _dispatch?_dispatch->GetMemberProperties(id,grfdexFetch,pgrfdex):E_FAIL; }
virtual HRESULT __stdcall GetMemberName(DISPID id,BSTR *pbstrName)
{ return _dispatch?_dispatch->GetMemberName(id,pbstrName):E_FAIL; }
virtual HRESULT __stdcall GetNextDispID(DWORD grfdex,DISPID id,DISPID *pid)
{ return _dispatch?_dispatch->GetNextDispID(grfdex,id,pid):E_FAIL; }
virtual HRESULT __stdcall GetNameSpaceParent(IUnknown **ppunk)
{ return _dispatch?_dispatch->GetNameSpaceParent(ppunk):E_FAIL; }
public:
iZombieScriptSite(IActiveScriptSite* del,IDispatchEx* disp){ _ref=1; _delegate=del; _dispatch=disp; }
void OwnerRelease(){ _delegate=0; _dispatch=0; Release(); }
protected:
virtual ~iZombieScriptSite()
{
_ref=_ref;
}
private:
long _ref;
IActiveScriptSite* _delegate;
IDispatchEx* _dispatch;
};
so you can everytime disconnect by _zombie->OwnerRelease() without consequences.
close script with:
_script->Close();
for releasing dependencies.
good luck.