Discussion:
Inter-dependant scripts not being unloaded correctly
(too old to reply)
Paul Baker [MVP, Windows - SDK]
2007-10-16 15:51:33 UTC
Permalink
(Please ignore my earlier post with the same subject. I seem to have hit
Send prematurely).

I wrote a scripting host that, similar to Windows Script Host (with multiple
script tags in a WSF file), allows multiple scripts that each have access to
code in all the other scripts.

The way I do this is described in this thead:
http://groups.google.com/group/microsoft.public.scripting.hosting/browse_thread/thread/38a7050525ee4e91

I have since discovered that scripts are sometimes not unloaded correctly
when I am done with them. The result of the IActiveScript.Release is
sometimes greater than 0 when I release it and objects in global variables
are not released. I can reproduce it in a simpler test program that does not
clone scripts or use threads. The test program is written in Delphi rather
than Visual Studio, but let me know if you want to see it. This is what it
does:

1. It initializes two scripts (let's call them Script1, Script2) using the
following sequence of calls:

Call CoCreateInstance to obtain an IActiveScript interface for the VBScript
engine
Call IActiveScript.SetScriptSite
Call IActiveScript.QueryInterface to obtain an IActiveScriptParse interface.
Call IActiveScriptParse.InitNew
Call IActiveScriptParse.ParseScriptTest

2. It connects Script1 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).

3. It adds Script1 to Script2 using IActiveScript.AddNamedItem(...,
SCRIPTITEM_ISVISIBLE or SCRIPTITEM_GLOBALMEMBERS). This ends up calling
IActiveScriptSite.GetItemInfo, so I call
IActiveScript.GetScriptDispatch(nil, ...). This allows Script2 to use
functions or global variables in Script1.

4. It connects Script2 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).

5. It adds Script2 to Script 1 using IActiveScript.AddNamed item, similar to
step 3. This allows Script1 to use functions or global variables in Script2
(Script1 already executed the inline code in step 2, but functions can later
be called using IDispatch that will take advantage of this).

6. It closes the scripts using IActiveScript.Close, first on Script1, then
on Script2.

7. It calls Script1.Release, then Script2.Release.

Exactly what happens depends on the content of the script, and can occur
even if they don't truly depend on each other.

Can anyone offer a suggestion as to what to look for next?

Thanks,

Paul
Walter Wang [MSFT]
2007-10-17 06:05:43 UTC
Permalink
Hi Paul,

I'm the one who had worked with you on the thread you mentioned. I'm glad
to work with you again on this post.

Please send me your test project. Although I had very limited knowledge on
Delphi, I will try to create an equivalent C++ program and reproduce the
issue on my side.

You can find my email address from my signature. Thanks.


Regards,
Walter Wang (***@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
Paul Baker [MVP, Windows - SDK]
2007-11-16 14:39:37 UTC
Permalink
For those who are following this, Microsoft has confirmed this as a bug
affecting both VBScript and JScript.

Paul
Post by Paul Baker [MVP, Windows - SDK]
(Please ignore my earlier post with the same subject. I seem to have hit
Send prematurely).
I wrote a scripting host that, similar to Windows Script Host (with
multiple script tags in a WSF file), allows multiple scripts that each
have access to code in all the other scripts.
http://groups.google.com/group/microsoft.public.scripting.hosting/browse_thread/thread/38a7050525ee4e91
I have since discovered that scripts are sometimes not unloaded correctly
when I am done with them. The result of the IActiveScript.Release is
sometimes greater than 0 when I release it and objects in global variables
are not released. I can reproduce it in a simpler test program that does
not clone scripts or use threads. The test program is written in Delphi
rather than Visual Studio, but let me know if you want to see it. This is
1. It initializes two scripts (let's call them Script1, Script2) using the
Call CoCreateInstance to obtain an IActiveScript interface for the
VBScript engine
Call IActiveScript.SetScriptSite
Call IActiveScript.QueryInterface to obtain an IActiveScriptParse interface.
Call IActiveScriptParse.InitNew
Call IActiveScriptParse.ParseScriptTest
2. It connects Script1 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).
3. It adds Script1 to Script2 using IActiveScript.AddNamedItem(...,
SCRIPTITEM_ISVISIBLE or SCRIPTITEM_GLOBALMEMBERS). This ends up calling
IActiveScriptSite.GetItemInfo, so I call
IActiveScript.GetScriptDispatch(nil, ...). This allows Script2 to use
functions or global variables in Script1.
4. It connects Script2 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).
5. It adds Script2 to Script 1 using IActiveScript.AddNamed item, similar
to step 3. This allows Script1 to use functions or global variables in
Script2 (Script1 already executed the inline code in step 2, but functions
can later be called using IDispatch that will take advantage of this).
6. It closes the scripts using IActiveScript.Close, first on Script1, then
on Script2.
7. It calls Script1.Release, then Script2.Release.
Exactly what happens depends on the content of the script, and can occur
even if they don't truly depend on each other.
Can anyone offer a suggestion as to what to look for next?
Thanks,
Paul
Paul Baker [MVP, Windows - SDK]
2007-12-10 18:44:11 UTC
Permalink
For those of you who may come across this article when researching writing a
scripting host, I have a solution.

This is not really a bug. It's just that Active Scripting cannot handle the
circular reference this causes.

Microsoft has provided me with a solution. It should call AddNamedItem only
once for each script using a global name. The global namespace is then
implemented using a single object that implements IDispatch.

IDispatch.GetIDsOfNames should call GetIDsOfNames on each script's IDispatch
interface until a script recognizes the name. It should then translate the
DispID provided by the script to a globally unique one. IDispatch.Invoke
should translate the globally unique DispID back to one that is recognized
by an individual script and call Invoke on the the script's IDispatch
interface. Name collisions must be avoided, I just use the first script that
recognizes the name.

Paul
Post by Paul Baker [MVP, Windows - SDK]
For those who are following this, Microsoft has confirmed this as a bug
affecting both VBScript and JScript.
Paul
Post by Paul Baker [MVP, Windows - SDK]
(Please ignore my earlier post with the same subject. I seem to have hit
Send prematurely).
I wrote a scripting host that, similar to Windows Script Host (with
multiple script tags in a WSF file), allows multiple scripts that each
have access to code in all the other scripts.
http://groups.google.com/group/microsoft.public.scripting.hosting/browse_thread/thread/38a7050525ee4e91
I have since discovered that scripts are sometimes not unloaded correctly
when I am done with them. The result of the IActiveScript.Release is
sometimes greater than 0 when I release it and objects in global
variables are not released. I can reproduce it in a simpler test program
that does not clone scripts or use threads. The test program is written
in Delphi rather than Visual Studio, but let me know if you want to see
1. It initializes two scripts (let's call them Script1, Script2) using
Call CoCreateInstance to obtain an IActiveScript interface for the
VBScript engine
Call IActiveScript.SetScriptSite
Call IActiveScript.QueryInterface to obtain an IActiveScriptParse interface.
Call IActiveScriptParse.InitNew
Call IActiveScriptParse.ParseScriptTest
2. It connects Script1 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).
3. It adds Script1 to Script2 using IActiveScript.AddNamedItem(...,
SCRIPTITEM_ISVISIBLE or SCRIPTITEM_GLOBALMEMBERS). This ends up calling
IActiveScriptSite.GetItemInfo, so I call
IActiveScript.GetScriptDispatch(nil, ...). This allows Script2 to use
functions or global variables in Script1.
4. It connects Script2 using
IActiveScript.SetScriptState(SCRIPTSTATE_CONNECTED).
5. It adds Script2 to Script 1 using IActiveScript.AddNamed item, similar
to step 3. This allows Script1 to use functions or global variables in
Script2 (Script1 already executed the inline code in step 2, but
functions can later be called using IDispatch that will take advantage of
this).
6. It closes the scripts using IActiveScript.Close, first on Script1,
then on Script2.
7. It calls Script1.Release, then Script2.Release.
Exactly what happens depends on the content of the script, and can occur
even if they don't truly depend on each other.
Can anyone offer a suggestion as to what to look for next?
Thanks,
Paul
Loading...