This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- FlexNet Connect
- :
- FlexNet Connect Forum
- :
- Re: COM interface to Agent.exe
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 05, 2003
05:07 AM
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:
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:
(5) Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 05, 2003
01:43 PM
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.
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.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 08, 2003
07:57 AM
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.
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.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 09, 2003
03:10 PM
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.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 11, 2003
07:13 AM
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
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
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Dec 12, 2003
03:23 AM
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
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