I need to find the product version of an installed application using the product code GUID. Is there a way to do this using a simple API call of some sort? I have found ways to do it using P/Invoke and the WindowsInstaller namespace, but I am trying to avoid using P/Invoke.
The Windows Installer exposes Win32 API functions (P/Invoke) as you have discovered. It also has COM automation interfaces that wrap these APIs but I'm sure you can guess is this is even less elegant. Windows Installer XML (WiX) Deployment Tools Foundation (DTF) has an MSI interop library that wraps it as managed code but I'm sure you can guess what it's doing under the covers: P/Invoke.
There are ways of getting it from the registry but this is not the official API and is less elegant IMO.
So to answer your question, you are already doing it in a very good and professional way.
If you want to get sneaky you can look through the registry to figure it out. When an MSI is installed windows creates a set of registry keys under:
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\<munged-ProductCode>
or
HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\<munged-ProductCode>
(depending on your machine/MSI bitness)
Under that registry location there should be a registry value named "ProductVersion". The trick is to know how to 'munge' a windows GUID (see http://www.vmwareinfo.com/2011/09/surgically-eliminating-windows.html).
Related
What are the differences between COM msi.dll WindowsInstaller and Microsoft.Deployment.WindowsInstaller?
I know one exists in %WINDIR%\system32\msi.dll and the other exists in Visual Studio's reference assemblies list.
I know the implementation of the Installer objects are completely different.
Why are there two different implementation of WindowsInstaller? and why are they called the same?
MSI API: The Windows Installer API is quite old and is implemented as Win32 C/C++ functions and a layer of COM automation on top (which you can use VBScript and many other languages to access). This is all implemented in the %WINDIR%\system32\msi.dll file (and whatever other support files are involved - I am not quite sure - there is also msiexec.exe of course - the actual installation engine and command line tool to install and configure MSI packages and msihnd.dll - and a few more I think).
DTF (Deployment Tools Foundation): As the .NET framework and managed code came of age, the use of COM and Win32 functions was kind of clunky and the Deployment Tools Foundation kit - also known as DTF was implemented to help use the MSI API with managed code. The file: Microsoft.Deployment.WindowsInstaller.dll is one of the files delivered as part of DTF and the most commonly used one. The WiX toolkit now installs DTF as part of its normal installation. Please check the links below.
Links:
A sample of DTF code and more details (recommended - see same page for COM).
The various APIs for MSI files.
Note, there are also some WMI functions.
I have looked at the Microsoft Forms 2.0 Object Library (FM20.DLL) and Microsoft Windows Common Controls (comctl32.dll), as both exist (I think) as OLE providers on my system. (I am doing this by opening them in VBA in Excel to look at the libraries with their members) and playing around with them in VBA.
My bigger problem is that I don't understand the relationship between the libraries themselves and ActiveX - how do I know which members can be created as ActiveX objects? (For example, you can create "Excel.Application", but not "MSForms.UserForm").
I want to be able to script (using OLE) a form using some library, display it, respond to events, etc. I would prefer using something that is already available (like the libraries mentioned above, if possible) to prevent having to install extra software.
If you can give an example (in any language) to get me started, that would be very helpful and much appreciated.
As per HansPassant's comment, what worked is using MS Forms 2.0, which has an ActiveX object, "Forms.Frame.1", which can be created and used in my program.
I found a program called ActiveXHelper, which allows one to see all the registered ActiveX objects on the system.
I am currently working on a project to perform disk defragmentation in Microsoft Windows environment. For that I want to use the in-built functions of the Windows defragmentation utility. I read somewhere that Windows uses "dfrgres.dll" file to perform defragmentation. So, I want to add "dfrgres.dll" file as a reference in my project. But I am not able to do so. This is the error message which I am getting when I try to add the specified DLL into my project:
"A reference to '...\dfrgres.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component"
Please tell me where the problem is...or is there any other way to do it...??? Are there any other open source resources available over the internet for defragmentation...???
Regards,
Mr. Elusive
There is no dedicated DLL or COM server to perform defrag, the low-level interface uses IOCTL codes to talk to the device driver. Briefly described here.
There's a Microsoft employee blog post that proposes a C# interface. No idea if it still works on later versions of Windows.
I want to create a Windows Installer, the 1st step I want it to call another installer (will install dependent components of my application), and the 2nd step I want to install my own application. I want to do all tasks in one installation process, and I have the dependent component installation package at hand (an exe file).
Any good tools or samples to refer to? I prefer to use VSTS or Microsoft or open source easy to use tools. :-)
thanks in advance,
George
You might want to take a look at the Microsoft Bootstrapper, assuming the dependent components are libraries such as .NET or similar then it's fairly straightforward.
If you want to create a Windows Installer (MSI) package then take a look at Windows Installer XML (WiX). But you'll want to get your head around how MSI works first. WiX is really simple once you understand Windows Installer, but trying to learn both at once can be rather confusing.
For a basic, copy some files, extract/run some stuff, type installer then NSIS is fairly straightforward scripting and you can pick that up in a day or so.
Nsis with this modification.
Update: It seems that nesting MSI installation is somewhat possible. However it requires some tweaking using tools from the Windows Installer SDK and has a number of drawbacks.
The following article has the details:
How to create a nested .msi package
Microsoft recommends not to use this feature (see this related answer and point 20 in this list).
However, you might also want to look at different install systems such as NSIS or create a bootstrapper that installs the dependencies prior to setup.
You could look at Inno Setup. It creates exe installers, as opposed to MSIs. It has a pascal-based scripting language, so is pretty flexible.
It's free and pretty easy to use.
If your existing installer doesn't use the MSI technology, you could use WiX to create an MSI and launch the existing installer via a custom action. I've done this in the past.
WiX is open source.
yes it would be very easy if you do it using Inno Setup, but with a slight difference..
You will have to perform step 2 first and then step 1.
Try using AutoHotkey(scripting) for checking the existence of any process in the background that verifies the installation of a particular software.
Check out iexpress on windows systems. In just a few minutes you can create an installer that can call as many installers as you like.
We are using a COM Object automation model to make our application available to our customers.
They are using for the most part python to access our applicaton interface.
As we want to be able to install (not yet run, that's another issue) different versions of the application, we are changing our COM components to be regfree.
But that conflicts with the access from scripting languages through IDispatch automation since they need the entries in the registry.
Our approach is to create an application which manages the active version of our actual application. It lets the user decide which version he wants to have and it takes care of the registry entries.
What are the alternatives to our approach?
There is a protocol within COM for doing this. If you version the Interfaces (and change the GUIDS for each version) you can install multiple versions. Microsoft does this with WORD etc.
It is possible to create a Word.Document.5 class which is specific to version 5 of the library, or just word.Document which will create an instance of the highest present on the machine. I'm not sure if this functionality is build into COM or needs to be impemented but it's worth looking into.
Regfree COM objects can be accessed through the Microsoft.Windows.ActCtx object.
As for IDispatch automation requiring entries in the registry -- that's not strictly correct. I presume you're using the default ATL implementation, IDispatchImpl.
We solved this solution by providing our own implementation, IRegFreeDispatchImpl, which used the activation context manipulation APIs in the manner suggested here to wrap all entry points into the DLL with an activation context activation/deactivation.
Well the answer is suggested by yourself. You can write an application which has complete list of all versions of COM components. Once a version is selected by user, you can call regsvr32 application to register that particular version.