none
Multiple Threads in an HTA Application RRS feed

  • Question

  • Hello all...

    What I am trying to do is to pass an element like an input to a COM DLL of an HTA Application, for instance:

    <input id="thisInput" value="foo"/>

    and then in script

    var x = ActiveXObject("MyDll.Dll");

    x.SetMonitor(thisInput);

    x.Start();

    while start is running, thisInput.value is set with progress items...

    in Start, I create a thread that does some work, and periodically calls thisInput.value = "some value", in reality this crashes the second it sets the value. If I move this from a thread to the Start method, this will work however it will only update after the call to x.Start() exits...

    Is this not possible to do? or is there a way I can get this to work?

    Thanks in advance!!

     

    Thursday, October 15, 2015 5:14 PM

Answers

  • so, are you saying that an HTML Element can ONLY be updated from the same thread that created it?

    I suspect that is the case. But that's something you're going to have to research on your own.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Jammer32 Thursday, October 15, 2015 7:59 PM
    Thursday, October 15, 2015 7:26 PM
    Moderator

All replies

  • There are no threads  in an HTA so we cannot understand what you are talking about.

    To get an element use:

    var el = document.GetElementById("thisinput");
    el.Value="some value";


    \_(ツ)_/

    Thursday, October 15, 2015 5:39 PM
  • There are no threads in an HTA. However you can force the script to yield.

    The following article explains this pretty succinctly:

    Updating the Display During Lengthy Operations


    -- Bill Stewart [Bill_Stewart]

    Thursday, October 15, 2015 5:47 PM
    Moderator
  • Seriously?

    I am not creating the thread in the HTA, I am creating the threads in a COM object...

    Notice!

    var x = ActiveXObject("MyDll.Dll");

    x.SetMonitor(thisInput);

    x.Start(); //<------ this is where the threads are created IN A COM OBJECT....

    Did you read the thread?

    Thanks!

    Thursday, October 15, 2015 5:53 PM
  • Yes, I read it. As already noted, HTAs are single-threaded only.

    What I was saying in my reply, is that you can yield the script in your HTA to the user temporarily before dispatching some code to update the UI (wait cursor, etc.).

    Another option would be to shell out to run something and retrieve the results. But you would still need to force the script to yield so that you don't block the user.

    I think you're answering back without a good understanding of the question you're really asking.


    -- Bill Stewart [Bill_Stewart]

    Thursday, October 15, 2015 6:03 PM
    Moderator
  • But COM is not single threaded... the threading occurs in the COM object... so, are you saying that an HTML Element can ONLY be updated from the same thread that created it?

    So your comment about HTAs being single threaded is meaningless unless you qualify that statement... because

    1. COM can create multiple threads.

    2. COM can Create multiple threads under the HTA host...

    3. The problem occurs when I update an elements value from a thread in a COM application...

    Thursday, October 15, 2015 6:09 PM
  • Still the info posted makes little sense and doeos not realy define a context for the question.

    The following code makes no sense eother:

    var x = ActiveXObject("MyDll.Dll");
    x.SetMonitor(thisInput);
    x.Start();

    Why?  Because "thisinput" does not exist as an object, variable or a string.  It is a string only as the ID of the object defining it.

    Effectlively you are passing a null to your dll.  This may cause the HTA to lock up if you do not have correct exception handling in place.

    What is it that you DLL is expecting as an argument? Since this is COM you cannot marshall an active component to another component or another thread.  You can only pass values.

    It is possible with the SDK to create extensions that are controls.  What yoou are doing is not an extension control.


    \_(ツ)_/

    Thursday, October 15, 2015 6:11 PM
  • Also.  In VBScript in an HTA/HTML script you can use the ID as an object but this does not work the same in JavaScript..

    \_(ツ)_/

    Thursday, October 15, 2015 6:12 PM
  • But COM is not single threaded... the threading occurs in the COM object... so, are you saying that an HTML Element can ONLY be updated from the same thread that created it?

    So your comment about HTAs being single threaded is meaningless unless you qualify that statement... because

    1. COM can create multiple threads.

    2. COM can Create multiple threads under the HTA host...

    3. The problem occurs when I update an elements value from a thread in a COM application...

    Again.  You cannot pass a object to a COM dll.  An HTA cannot share objects with an external thread.  An HTA can send and receive values from an external COM object.

    Study how Media player interacts.  It does so only by calling command methods or setting/reading values from the player.

    A COM object can raise events that can be used to set values as an event can send data t the event handler.


    \_(ツ)_/

    Thursday, October 15, 2015 6:16 PM
  • uhm, wow...

    jrv... that is some goofy stuff there

    1. yes, you can send an active component as a parameter to another component..

    2. yes, thisInput is an object...

    3. this works (meaning the object is good, it is not null, has all the properties it needs) when the object is accessed in the method and not passed to the thread...

    Thursday, October 15, 2015 6:20 PM
  • uhm, wow...

    jrv... that is some goofy stuff there

    1. yes, you can send an active component as a parameter to another component..

    2. yes, thisInput is an object...

    3. this works (meaning the object is good, it is not null, has all the properties it needs) when the object is accessed in the method and not passed to the thread...

    Not on another thread and the JS will not always produce a control with that syntax.  In many events the other controls cannot be referenced by ID.

    If you do not create a new thread for your COM (that is run it on the caller thread) you can share data and raise events.  If it is an ActiveX then it can call into the HTA controls but ActiveX won't work on 64 bit systems.


    \_(ツ)_/

    Thursday, October 15, 2015 6:25 PM
  •  An HTA cannot share objects with an external thread

    See now, you can read.. this is the answer I was looking for...

    Where is this documented? Where did you get this handy piece of info?

    Also

    A COM object can raise events that can be used to set values as an event can send data t the event handler.
    Is there an example of setting up an event sync in HTA? is this async or does it entail polling? and where is this documented? Thanks
    Thursday, October 15, 2015 6:29 PM
  •  An HTA cannot share objects with an external thread

    See now, you can read.. this is the answer I was looking for...

    Where is this documented? Where did you get this handy piece of info?

    Also

    A COM object can raise events that can be used to set values as an event can send data t the event handler.

    Is there an example of setting up an event sync in HTA? is this async or does it entail polling? and where is this documented? Thanks

    These questions are all for the developer forums.  They will step you through how to declare interfaces and events in a way that work in the HTML environment.

    I know these  things because a spent a year+ building solutions for client side forms prior to that advent of ASP.Net. I just went looking for that old SDK documentation but is is too old to find online.  The programming environment has changed but the rules of COM have not.  

    Post your concerns in the C# developers forum to get guidance on how t use COM with an application like MSHTA.

    Any correctly designed COM object can raise events and they can be bund to in HTML.  The object has to be registered as an object to the HTML using the <object> tag.  The events are defined by <objectname>_<eventname>.  A button named "mybut" registers a click with mybut_click.  In javascript use JS forms to bind or define the event handler.


    \_(ツ)_/

    Thursday, October 15, 2015 6:39 PM
  • okay.... its obvious to me that you have no clue what you are talking about...

    Sending me to a C# forum? When this is HTA? Wow...

    I have been doing this for over 20 years, and your answers are noob answers to a noobier noob...

    You say that HTA cannot do things but tell me that COM hasn't changed in years, and to reach out to the developers at c#? Your single answer:

         An HTA cannot share objects with an external thread

    Is the only thing that made remotely any sense, however you know this because of your 1 year experience ??

    Please stay out of any questions I may ask in the future...

    That is all....

    Thursday, October 15, 2015 6:46 PM
  • Is your DLL written in "HTA".

    There is no need to get nasty.  It makes it look like you are just trying to cause trouble.

    This is a scripting forum.  We have no idea what is in you DLL.  The issue is not caused by HTA code but is caused by your DLL  and lack of knowledge of threading and COM.  The developers forum is the appropriate place to ask you questions about COM interop.


    \_(ツ)_/

    Thursday, October 15, 2015 6:51 PM
  • HA!!!

    You have idea what my knowledge of com or threading is... DLL works and works fine :)

    The internals of the DLL are irrelevant other than I am calling

    <object>.value = "Some Value"

    This is related to HTA and the HTA host, since the component works fine in every single application it has been used in, there is an issue I need to overcome in HTA and the HTA Host only....

    Therefore, if you do not know the answer, then you shouldn't comment...

    thanks...

    Thursday, October 15, 2015 7:09 PM
  • so, are you saying that an HTML Element can ONLY be updated from the same thread that created it?

    I suspect that is the case. But that's something you're going to have to research on your own.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Jammer32 Thursday, October 15, 2015 7:59 PM
    Thursday, October 15, 2015 7:26 PM
    Moderator
  • You are claiming to update from a multi-threaded application from a single threaded application.  When you send an object via COM none of the methods can be sent and the properties cannot be update inn the calling app.  The rules of creating an object that is callable from an MSHTA are out there but they are not scripting issues.  They have too do with how you design the DLL.  The DLL can work perfectly with test aps and many other apps but will only work with certain kinds of apps because of how it is declared.

    Take FSO a an example.  It is callable but does not allow and objects to be passed.

    WMI is a very complex and "scriptable" object.  It can send back events.  That is well documented.

    Since VBScript and HTAs are pretty much deprecated and soon to be obsolete the documentation and building DLL extensions is disappearing.

    I have been building COM DLLs, ActiveX controls and custom controls for 20 years.  We were designing applications using DDE before COM was developed.  COM is very useful but it is very finicky.  It is sensitive the the calling environment.  Calling COM from script requires extra steps in the registration and design.

    As an example here is how MS delivers the WMI script objects: https://technet.microsoft.com/en-us/library/ee198924.aspx?f=255&MSPPError=-2147217396 WMI script objects can raise events to VBScript. Jscript and HTA scripts.  It is in the linked documentation.  Unfortunately the examples of how to do this are all in "C" and are now hard to find.

    The same is true of things like the FSO.  Many try to use the Shell object with script and find that it doesn't.  MS has made it clear that it was not designed to work in a scripted environment.


    \_(ツ)_/

    Thursday, October 15, 2015 7:41 PM
  • Here are the scriptable shell interfaces and examples of how to use them in jscript.

    https://msdn.microsoft.com/en-us/library/windows/desktop/bb776890(v=vs.85).aspx

    Here is an example of receiving an event from the WMI object:
    https://msdn.microsoft.com/en-us/library/aa393013(v=vs.85).aspx

    Here is some of the documentation describing the methods of adding interactive components using ATL/COM with "C". It is called "binary behaviors" when it is page interactive on the client side.

    https://msdn.microsoft.com/en-us/library/aa744100(v=vs.85).aspx

    Straight COM cannot interact outside of trading values and sending events.  Binary Behaviors have been mostly abandoned in favor of HTC controls and JavaScript controls.  Me implements gradients and other special effects as Binary Behaviors.  The interactivity is still limited too the COM isolation.

    The biggest misunderstanding for beginning COM programmers is thinking that a scripted environment is a application like any other but it isn't.  It is a "late bound" environment and as such limits what can be done versus hosting a control in an application as an early bound (compiled and linked) object.  Any time you see GetObject or CreateObject you are dealing with a late bound object.

    In VB we can add many objects by referencing the TLB.  Foor example these can be linked using "Dim obj As New ADORecordset" and the object will behave differently then "Set obj = CreateObject("ADODB.Recordset")"

    Some objects can be both early and late bound and some can only be early bound.

    Your DLL is being loaded as a "late bound" DLL which limits much of its interaction.  YU can load it in C# or VB.Net as a reference ("early bound or linked") and it will work more like you expect.  The difference is "linked in" and "hosted".


    \_(ツ)_/


    • Edited by jrv Thursday, October 15, 2015 8:01 PM
    Thursday, October 15, 2015 7:53 PM
  • dude...

    sorry.... just stop responding...

    Thursday, October 15, 2015 7:56 PM
  • Not that it matters here.... but

    1. this is possible...

    2. your COM method must be early bound to the element you want to use (IE)

    function Update(HTMLInputElement thisElement)

    instead of

    function Update(object thisElement)

    no more crashes... and the HTMLElement can be updated from any thread...

    Friday, October 16, 2015 7:00 PM
  • Can't be done in an HTA.  Scripts cannot be early bound.  Scripts cannot declare call types.

    In the source from your DLL you can  declare a type and it may work but it still has many limitations.  Adding a call type to a C# function has nothing to do with "early bound". 

    This is why I recommended posting in the C# developers forum.  The issue cannot be solved by changing the HTA.


    \_(ツ)_/


    • Edited by jrv Friday, October 16, 2015 7:07 PM
    Friday, October 16, 2015 7:05 PM
  • seriously dude... stop responding...
    Friday, October 16, 2015 8:44 PM
  • What is your problem?  You post preposterous things and proceed too be rude. Don't call people "dude".  It gives away the fact that you are still in junior high school and are a bit arrogant.


    \_(ツ)_/

    Friday, October 16, 2015 9:03 PM
  • What?

    Other than the fact you don't know anything and prove this by posting stuff that is completely incorrect, I could care less what you think dude...

    So, if you don't want to be aggravated.... then stop answering.. simple as that...

    Friday, October 16, 2015 9:11 PM