Reading PARAM from HTML OBJECT into EXE inside CAB

OK a simple question.

I have a signed CAB called ""
containing an executable called "test.exe"
and an INF file called "test.inf"

This is not an ACTIVEX program just a normal win32 APP that is run through a signed CAB.  All that is required in the INF file is the following.

[Setup Hooks]

To run "test.exe" from the webpage (after accepting the signed certificate) the following OBJECT tag is used.

<OBJECT CLASSID="CLSID:15589FA1-C456-11CE-BF01-A0055595A">

OK ... all is fine.  BUT now I want to use a PARAM tag in the object which I can pickup in my executable.  This is so easy to do with a JAVA applet but I have no idea within a win32 app.

ie. put
<PARAM NAME="id" VALUE="666">
within the OBJECT html and read in the variable id at runtime within the EXE.

Thats all.

Thanks in advance

Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

DanRollinsConnect With a Mentor Commented:
5) Edit ParmReader.cpp.  Make it so:

// ParmReader.cpp : Implementation of CParmReader
#include "stdafx.h"
#include "Starter.h"
#include "ParmReader.h"

// CParmReader

STDMETHODIMP CParmReader::Load(IPropertyBag* pPropBag,IErrorLog* pErrorLog)
    if (0 == pPropBag) {
    VARIANT varMyNum;
    VARIANT varMyName;

    /* convert, store or work with results here */

     return( S_OK );
6) Build: It should compile and link without errors

7) Create this file, named C:\Temp\ParmTest.htm
 Hi there!<br>
 <OBJECT name="WhoCares"
 <PARAM NAME="mynum"  value="12">
 <PARAM NAME="myname" value="Dan">


Open up Starter.idl.  Copy the lowest GUID.  It is just above
   helpstring("ParmReader Class")

Paste that GUID into the HTM file, replacing the ......

Save the HTML file

I am now going to sabve you a LOT of time and effort:  

8) Place a breakpoint in CParmReader::Load()

9) Attempt to run/debug the Starter.DLL
It will prompt "what executable?".  Click > and choose Default Browser.

10) Click OK.  An empty IE will appear.  

11) Drag the HTML file and drop it into the browser (or type its full path into the address field).

That causes the ActiveX control to be instantiated.  The browser sees that there are parms so it queries the control for IPersistPropertyBag, finds it and calls its Load() member.

12) Execution stop at the breakpoint you set in step 8.  Single-step and note that the parms are indeed available for your hacking pleasure.

I have never done this before.  It took several hours to work it all out.

-- Dan
Check out the environment variables :o)
chullandAuthor Commented:
Please elaborate with an example.
The new generation of project management tools

With’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

chullandAuthor Commented:
I don't want to use cookies either,
Just want a solution as simple as it is in JAVA

userid = Integer.parseInt(getParameter("id"));

There must be a way as simple in c++ as there is in Java.
I'm sorry I was so ambiguous...

>> What compiler are you developing in?

The PARAM statements just set ActiveX properties - create the properties. This will make it VERY easy to implement.

Otherwise you have to check your environment using interface calls.

It's easiest if you read up on your own compiler's help file about ActiveX properties... but if you're using an IDE you should be able to do it very quickly indeed and then you can just reference the property to find the value.
chullandAuthor Commented:
What has this to do with the compiler? Like I said before its not really an activex component (com object) just a simple win32 inside a CAB.  An installer, thats all.

All I need to do is call the "installer" with different options WITHOUT the need to "re-cab".

Its just the same as calling any executable with command line options .... in this case the options are required to be taken from the OBJECT tag.

ANY code examples of how to retrieve the PARAM tag in VC++ will be helpfull.
>> <OBJECT CLASSID="CLSID:15589FA1-C456-11CE-BF01-A0055595A">

Do you know which object's CLSID this is ?

Its either an installer or extractor that uses codebase to download and extract and run the cab files
You app must definitely have this object otherwise the object creation in HTML would fail and report an error.

In either case check if that object supports passing params to the extractable or the executable after it is extracted. If its an installer it most definitely has support for command line params etc. In either case post some information about that object.

How do you specify that test.exe be run after extraction, can you not specify additional command line params there ?

You can most definitely retrieve PARAM tags in VC++, but would it really help or even aply at all here. How would you access the HTML document ??? This is going to be a hard ride if at all
Standard Exe programs do not implement a method to access the PARAM= value.  I can suggest several options:

* EXEs can read data from the command line, so you could change the run= line in your INF file.

* Add an INI file to the CAB and have the EXE read from it.

* Rewrite your EXE so that it is an ActiveX object that implements IPersistPropertyBag

* Write a small ActiveX wrapper that reads the PARAMs and passes them to the EXE on its command line or via another mechanism

* Try some tests... maybe the installation component passes the PARAM values on the command line (I have seen nothing that even suggests this, but what the heck, its worth a try).

-- Dan
chullandAuthor Commented:
Thanks for you replys, let me try and answer your answers in more detail.

* Do you know which object's CLSID this is ?
This is taken straight from Microsoft support using a method call "Internet Code Download Linking";EN-US;q232077
It's a method to run executables from webpages.  It does run very much like an installer.

* How do you specify that test.exe be run after extraction, can you not specify additional command line
params there ?
If you look at what is in my INF file you can see run=%EXTRACT_DIR%\test.exe

Now to answer both people on this fact that I can add command line options to this.... yes I could but this INF is contained within the signed CAB.  I need to call the program from OUTSIDE with various command line options depending on my HTML form options, so this is not possible.

* Rewrite your EXE so that it is an ActiveX object that implements IPersistPropertyBag
This is a very drastic way of curing a problem although it would work I admit :)

* Write a small ActiveX wrapper that reads the PARAMs and passes them to the EXE on its command line
or via another mechanism
Yes this would be another way.  Basically use a small activex program to download the larger program to disk then run with command line options.... but thats why I asked the question.  Its very easy to do this in a signed java Applet in about 40 lines of code.  I wanted to see if anyone knew a straight forward way of doing it.

Ok I'll continue to do tests myself, if anyone has any other ideas then please post.


>> Basically use a small activex program to download the larger program...

Not what I meant.  The cab could contain both files (treat the EXE as a dependency, e.g., like a DLL required by the ActiveX).  When the ActiveX gets control, it reads the PARAM settings and formulates a rich commandline and then launches the EXE.

I'm not saying this is the best way, but it might work.

I did some testing, and found that the PARAM= values do not end up as commandline arguments or in the process environment strings.

-- Dan
chullandAuthor Commented:
Hi Dan

Done tests also and can't get anything from command line either.  Also tried just using a signed EXE rather than a CAB but the CODEBASE tag won't allow options after the .exe

The Small ActiveX interface like you suggested looks the best way at the moment but I wanted to avoid it.  I wouldn't really know where to start with it either.  An example of how this would be done would be very usefull.

Its strange that such a "simple" task cannot be performed, but I guess that IE for you.

>>but I guess that IE for you.
Does it work with Netscape or Opera?  Just curious.  If you shoot your horse, you have to walk...

-- Dan
>>An example of how this would be done would
be very usefull.

1) New project, ATL COM AppWizard
   Name: Starter
2) Dynamic Link Libraty (DLL)
   [x] Allow merging of proxy/stub
3) ClassView, select Starter
   Right-click: New ALT Object
   Simple Object
4) Edit ParmReader.h to...

// ParmReader.h : Declaration of the CParmReader

#ifndef __PARMREADER_H_
#define __PARMREADER_H_

#include "resource.h"       // main symbols
#include <atlctl.h>

// CParmReader
class ATL_NO_VTABLE CParmReader :
     public CComObjectRootEx<CComSingleThreadModel>,
     public IDispatchImpl<IParmReader, &IID_IParmReader, &LIBID_STARTERLib>,
     public CComControl<CParmReader>,
     public CComCoClass<CParmReader, &CLSID_ParmReader>,
     public IPersistPropertyBagImpl<CParmReader>
     // --- added
     STDMETHODIMP Load(IPropertyBag* pPropBag,IErrorLog* pErrorLog);



     COM_INTERFACE_ENTRY(IPersistPropertyBag) // <<-- added

     PROP_DATA_ENTRY("_cx",, VT_UI4)
     PROP_DATA_ENTRY("_cy",, VT_UI4)
     // Example entries
     // PROP_ENTRY("Property Description", dispid, clsid)
     // PROP_PAGE(CLSID_StockColorPage)

// IParmReader

#endif //__PARMREADER_H_

chullandAuthor Commented:
Hi Dan,

You've been busy!  The code compiled and worked as you stated.  As far as an activeX solution goes you have given more than an adequate answer.  

I'm still disappointed that a more straight forward way of passing the PARAM through to an executable isn't available.  The size of the DLL created was itself over 20k with a release version which is half the size of the original install program, just to pass a variable to it.

I have played around with a few different options.  One was to write a cookie and my EXE read it back, another was to make a small Java Applet.  Both work fine but Cookies and Applets can both be "switched off" as indeed can ActiveX.  There is also the problem with different browsers as you mentioned, IE, Netscape, Opera and even AOL's.

I came up with a VERY simple solution to all this.

The browser window, that is thrown up allowing the download wether by signed code or simple "run from location" can have a title.  For instance "Download File".  If this title is changed to have extra info such as the information I wanted to pass in the PARAM ie. "Download-ID123" then we can use this.

In the downloaded EXE, I've added a routine that scans all IE windows and checks their titles for an ID.  The program can then execute according to that information.


This can easily be extended to include Netscape, Opera and AOL.  Here's the code, its very small.

static BOOL CALLBACK getid(HWND hwnd, LPARAM lParam)
  char title[32];
  char classname[32];

  GetWindowText(hwnd, title, 32);
  GetClassName(hwnd, classname, 32);

  if (strcmp(classname, "IEFrame") == 0 || strcmp(classname, "CabinetWClass") == 0}
      // Strip ID off here and check if valid.
      // If OK set a variable.  Thats it!
     return TRUE;

void CJPDApp::checkID()
     EnumWindows((WNDENUMPROC)getid, (LPARAM)NULL);

Please give your comments.
>>There must be a way as simple in c++ as there is in Java.

>>Its strange that such a "simple" task cannot be performed, but I guess that IE for you.

>> I'm still disappointed that a more straight forward way
>> of passing the PARAM through to an executable isn't available.

Win32 C++ apps are inherently dangerous since they have full access to the computer.  For instance, it is possible to format the hard disk, or spam out thousands of emails or install a keyboard hook to monitor keyboard usage for passwords... etc.  So it shouldn't be too hard to understand why Microsoft does not make it easy to allow a click in a browser to cause download and execute an arbitrary program.  In fact, whenever somebody discovers a way to do that, Microsoft immediately comes out with a "Critical Update" to fix a "serious security breach."

Your technique of reading a parameter off of the download window title sounds like it will work for your application.

-- Dan
chullandAuthor Commented:
Hi Dan,

Any App, ActiveX, Java Applet etc can do such harm if used with a signed certificate.  Thats what its there for, the mechanism should be available to pass those variables if the app is signed.  It appears Microsoft overlooked this particular instance.

Anyway the solution for my particular app is working well as long as the download window remains open as the app starts to run.

I think your ActiveX answer was a good one for most people so it would be sensible to close this question and at least award you some of the points.

Thanks for your help on this.

I'm glad I could help.  -- Dan
All Courses

From novice to tech pro — start learning today.