cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
mooney
Level 3

COM interface to Agent.exe

I've managed to invoke Update Service from a prototype C++ application, using the COM interface, and everything works great.

I did this using the #import directive,

i.e. #import "C:\Program Files\Common Files\InstallShield\UpdateService\Agent.exe" named_guids no_namespace raw_interfaces_only

I now need to get this functionality into a released product, which means that upto 20 developers will need to be able to compile the source code. Not all of the developers have InstallShield licences so they won't have agent.exe installed on their machines and the compilation will fail.

Is there a type library available for Update Service or can anyone recommend a way around this problem?

Note that I need to use the COM interface rather than the command line interface because we are running the update installations silently using AutoUpdate() but need to be able to capture error messages for logging purposes. I have tried to use automation, via Visual C++ Class Wizard, to create a class imported from the Agent.exe but the function prototypes do not return any error information.

Any help would be greatly appreciated as I am new to both COM and Update Service.

Thanks
Michelle :confused:
0 Kudos
(5) Replies
ProductManager
Level 6

Couldn't they just install the update service sdk, Its not like there installing your Authoring tool (ie..developer, devstudio, etc..). I dont think there should be any licensing issue for them to have the ISUS SDK installed.

Maybe ask your IS sales rep if you want to know for sure, but I dont think there would be a problem with each of them having the SDK installed on each of there machines.
0 Kudos
mooney
Level 3

There is a further issue in that we are developing our software for a customer and they have purchased the Update Service licence.

My company therefore does not have an Update Service licence and so does not want all of the developers to install the Update Service SDK, which is only available for download once a licence has been purchased.

Is there any way that we can get around the dependency on agent.exe? If a type library was available we could simply include this in the Visual C++ workspace.
0 Kudos
Chris_Woerner
Level 10

There is no license issue with the SDK. It can be installed on any development machine. In fact, that is why we made a seperate installation from our installer tools - so that it could be installed on developer machines.
0 Kudos
leifop
Level 3

You can create a header file (.tlh) from the agent.exe file that you can use (#include) in your code instead of the #import statement. This way, other developers don't need agent.exe (or sdk) installed. Of course, they will get run-time COM errors if agent.exe is not installed, but these should be handled by your application anyway, e.g. silently. In any case, other developers don't need to install the complete SDK.

Important: You have to re-create the tlh file (using #import) each time you update your agent.exe file.

I have the following code snippet at the top of my source file:

....
// Following line creates Agent.tlh (if exe has been updated)
//#import "C:\Program Files\Common Files\InstallShield\UpdateService\Agent.exe" named_guids no_namespace raw_interfaces_only
// This file contains the interface definitions
#include "agent.tlh"
....

When I install a new version of the SDK I uncomment the #import line the first time I compile the source, to create a new tlh-file. Otherwise I leave this line commented.

Regards,
Leif
0 Kudos
mooney
Level 3

Thanks Leif,

Your suggestion is a good one; especially as most of the developers simply need to compile against this software and don't actually need to execute the Update Service functions.

As I said before I am new to COM but in reading up about the subject I have found that you can use IDispatch to avoid compilation dependencies altogether. The source code is not straight forward or easy to understand but it works and only developers that need to use the Update Service functionality have to install the Update Service SDK!

Here is what I did, note that you need to use the Microsoft OLE/COM object viewer tool that ships with Visual C++ to determine the interface to AutoUpdate():

COleDispatchDriver m_app;

void CAgentEventsDlg::OnStartup()
{
// Check to see if you've already started the server.
if (m_app.m_lpDispatch != NULL)
{
AfxMessageBox("Server already started.");
return;
}

char buf[256]; // General purpose buffer.

// Start Automation server for Agent.exe.
COleException e;
if (!m_app.CreateDispatch("DWUpdateService.Agent", &e))
{
sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",e.m_sc, e.m_sc);
AfxMessageBox(buf, MB_SETFOREGROUND);
return;
}
}

void CAgentEventsDlg::OnUpdate()
{
BOOL bRetVal = FALSE;

// Call AutoUpdate through automation.

BOOL result;
DISPID dispID;
unsigned short *ucPtr;

// First we determine the dispatch id of the AutoUpdate() function
ucPtr = L"AutoUpdate";
m_app.m_lpDispatch->GetIDsOfNames(
IID_NULL, &ucPtr, 1, LOCALE_USER_DEFAULT, &dispID
);

// Then we define the parameter list,
// i.e. Product Code (String), Silent (bool), Options (long), ExtraInfo (long)
BYTE *parmStr;
parmStr = (BYTE *)( VTS_BSTR VTS_BOOL VTS_I4 VTS_I4 );

// Invoke AutoUpdate() with the appropriate parameters
m_app.InvokeHelper(dispID,
DISPATCH_METHOD,
VT_BOOL,
(void*)&result,
parmStr,
"{BD3AC9B8-C3B9-47D3-B726-CBF022F645D3}",
FALSE, 0, 0);

bRetVal = result; // returns whether an update was available or not
}

void CAgentEventsDlg::OnStop()
{
// Check if you've started the server.
if(m_app.m_lpDispatch == NULL)
{
AfxMessageBox("You haven't started the server yet.");
return;
}

// Release application object.
m_app.ReleaseDispatch();
}

Hope this helps anyone else stuck in the same situation, note that I'm still working how to determine error messages and use events.

Thanks
Michelle
0 Kudos