Get reference to objects in called script?

Anything VBScript-related, including Windows Script Host, WMI, ADSI, and more.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 14 years and 3 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
kenthompson
Posts: 14
Last visit: Tue Mar 02, 2010 3:39 am

Get reference to objects in called script?

Post by kenthompson »

Hello,
I have an hta that calls a vbs, which in turn instantiates MS Word and MS Excel. It scrapes the word doc (which must follow a certain format) and with info gleaned from the user in the hta creates a spreadsheet out of the data from the word doc. (on which the user will choose row specific options from dropdowns and then load into Quality Center as requirements). While this process is happening the hta GUI is running a "processing..." window waiting for the process to finish. The "processing..." window has a cancel button to kill it all if something is wrong.
So, the problem I am trying to address is that when the doc is not properly formatted it can obviously cause problems for the scraping of the word doc. In certain situations this can cause a loop that is too tight for my original 'cancel' routine to catch it, and the app is hung. The original cancel routine was simply enviroment variables as flags that got checked during processing.
So, I reworked it and now my cancel routine is a WMI process that kills the wscript.exe (this all happens in the hta, off the cancel button click event).
What I cannot figure out is how to properly shut down Word and Excel when canceling. They both get created in the vbs with regular Set objWord = CreateObject ("Word.application") syntax.
Is there a way to pass the objWord back to the hta so it can close and quit the applications? Or, less attractive but certainly workable, is there a way to capture the ProcessIDs of these apps? I know I can kill all running excel.exe and winword.exe, but I'd rather not kill other docs the user might have open and possibly cause a loss of data. I tried to find some WMI unique property to ID them, but the only thing I could see was ParentProcessID, which would have worked except the parent of the apps is not the wscript.exe process, but a svchost process. So that doesn"t help.
Any suggestions will be appreciated.

Thanks,
Ken
User avatar
kenthompson
Posts: 14
Last visit: Tue Mar 02, 2010 3:39 am

Get reference to objects in called script?

Post by kenthompson »

The only response I get to this question is to completely redesign the application. I guess it's assumed that the design is arbitrary? I guess I am confused, as I was under the impression that seperating interface from processing was standard design. The specific reason they are seperated is so that the "please wait..." (a gif mock progress bar) window keeps the gif running. When the processing is in the hta, the gif stalls while the processing is taking place, making it appear that the app is hung.
Regardless, a complete redesign is not an option.

I am using a little routine to do some validation on the doc before processing it. But it's not catching everything that users can come up with. I guess I will try to beef that up since apparently passing any kind of handle to the MS Office apps from vbs to hta is apparently impossible.

Thanks for your help on this.
Ken kenthompson2010-02-24 07:40:09
User avatar
kenthompson
Posts: 14
Last visit: Tue Mar 02, 2010 3:39 am

Get reference to objects in called script?

Post by kenthompson »


When COM objects are launched they are, by necessity, launched asynchronously. This also means that you cannot have a reference to one that is sharable except that you can return the process ID and use that as a Kill mechanism. The only waay to pass this process id would be through a file so puti it in a file and read the file from the GUI. YO8 can then use WMI to get a reference to the process and kill it.


You're always an excellent source, jvierra. Thanks for all the info. What you explain in the bit I quoted here is exactly what I was trying to do. So, how do you get the processID? I know how to get it when you're starting something with WMI and getting the processID as a return. But when starting apps through the COM, how can you get the processID you are initiating?
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Get reference to objects in called script?

Post by jvierra »

With COM you need to search for process ID. With WScript.Exec the process ID is returned in the control structure at launch.

If we could see your actual code I bet we could find an easy way to do what yoou want. In cases like this I have found that, most of the time, the approach can be simplified to gain all requierd functional elements. I say "most of the time" because sometimes the problem can't be fixed without changing the requirements or tools.

jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Get reference to objects in called script?

Post by jvierra »


Thought I would take a minute to try and describe what is happening and why it presents such a problem.

When you launch a COM process like Excel or Word you are creating an object that does not run "in-process" so when the VBScript finishes the Excel/Word application will not be terminated. Why is this?


A COM application does not have a parent child relationship that is dependent in a way that quitting th eparent wil also quit the cuild. WHile this seems to be tru of in-process activations like winmgmts:, LDAP: or Scripting.FileSystemObject; the latter activations are not applications but are DLLs that are loaded into the current or calling address space hence "IN-process" activation.

COM applications require an explicit shutdown that can only, for security, stability and data integrity reasons, come from the active application itself. Some applications and service will allow an external controller application to send them a message causing a shutdown but the application still shuts itself down on request.

When VBScript launches Excel it does it through the system
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Get reference to objects in called script?

Post by jvierra »

You can alway upload as a zip file which is allowed and encouraged.

The modal dialog wil not really get you where you want. Yoy probably want to try to use a modelss dialog however if a piece of code is waiting anywher in any of the HTA or any dialog then everything will hang on that wait.


Any script that has more than a couple of 100 lines of coed should be considered an application and moved to a more robust environment in my opinion.

Here are some samples: uploads/2491/HTASampler.zip
uploads/2491/IEDOMExamples.zip

Good Luck
jvierra2010-02-25 07:14:06
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Get reference to objects in called script?

Post by jvierra »

You still cannot get paste teh fact that you will still be single threaded. An HTA has only one thread and any time it is waiting on anything the whole HTA will wait. Trting to juggle things nearly always leads to a deadlock.

When you need to grab Word doc info into an Excel SPreadsheet it is far eeaier and more controllable to put the VB code into Excel and let it manage the word doc. Excel can be given a user interface that is even better than an HTA.

The other plus with Office VBA is that you can use callbacks and async calls which you cannot use in an HTA or in vbscript with mode objects. VBScript has no mechanism to declare a callback method but VBA does.

YOu will, however, gain from moving everything into the HTA a Rasimmer pointed out earlier. YOu will have th3e object interfaces all in one application and, assuming you don't deadlock or lose the context, you will be able to "Quit" the external Office apps.

User avatar
kenthompson
Posts: 14
Last visit: Tue Mar 02, 2010 3:39 am

Get reference to objects in called script?

Post by kenthompson »

I"ve got it working now. I was using window.close in the cancel routine, but the code was still processing. I changed the window.close to a wmi terminate and now it closes the MS Apps correctly and kills the mshta. Works fine.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Get reference to objects in called script?

Post by jvierra »

Not sure what you are talking about or what you are trying to do.

windows.close is used to close an HTML window and has nothing to do with an application except if it is the mainwindow of an HTML app (HTA).

If you are apble to spawn your script with Exec which I was lead to believe couldn't bedone then you can always kill it with WMI by querying for the PID. If you have a Proc block received from Exec the just use teh proc block to terminate the app. No need for WMI.

This will not alow you to kill an object spawned from your external script though.

Here is example:

Code: Select all

Set wsshell = CreateObject("WScript.Shell")
Set proc = wsshell.Exec("notepad.exe")
proc.Terminate

It is far easier to start Word or Excel like this:

Code: Select all

Set wrd = CreateObject("Word.Application")
set doc = wrd.Documents.Open("e:testtest.doc")
doc.Activate
doc.ActiveWindow.Visible = True
wrd.ActiveWindow.Close False
wrd.Application.Quit

This can be done from an HTA.

If teh WMI method does what you want then use it. Keep in mind that the above can be very useful in most situations as they give you more complete and direct control of the apps.
User avatar
kenthompson
Posts: 14
Last visit: Tue Mar 02, 2010 3:39 am

Get reference to objects in called script?

Post by kenthompson »

It required killing because I was originally using window.close in the cancel routine and it was causing problems.

I'll show you since I don't seem to be able to explain it.

The child window that was generated with a showmodelessdialogue has this button:
-------------------------------------------------------------------------------------------
<input id="can" type="button" value="Cancel" name="can_button" class="btn" onClick="Window_Cancel()" onmouseover="can.className='btn btnhov'" onmouseout="can.className='btn'" >
-------------------------------------------------------------------------------------------
which runs this:
-------------------------------------------------------------------------------------------
Sub Window_Cancelset sData = window.dialogArguments sData.StopScraper()End Sub
-------------------------------------------------------------------------------------------
which in turn, runs this (which is in the main hta(parent))
-------------------------------------------------------------------------------------------
Sub StopScraper() If IsObject(objQCConnection) = True then If objQCConnection.Connected Then objQCConnection.Disconnect End If If objQCConnection.LoggedIn Then objQCConnection.Logout End If Set objQCConnection = Nothing End if If IsObject(objExcel) = true Then objExcel.Visible = True Set objExcel = Nothing End If

If IsObject(objWord) = true Then objWord.Documents.Close(0) '0 = wddonotsavechanges objWord.Application.quit Set objWord = Nothing End If window.CloseEnd Sub
-------------------------------------------------------------------------------------------

So when the cancel was clicked it did everything it was supposed to, but the 'processing' of the MS Apps was continuing. (which happens in the main hta, everything happens in the main hta except that child window with the cancel button) So, as MS Word is shut down mshta throws an error because it's still trying to process the word doc, but the word doc isn't there.

So, window.close was not killing the hta process.
So, I replaced the window.close with the wmi routine I posted earlier. Now it shuts everything down (except Excel, which I just make visible). and closes with no errors.

This topic is 14 years and 3 weeks old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked