Tuesday, June 21, 2011

Removing the Installshield Brand from the dialogs in Basic MSI type projects

Hello Friends, yesterday my client told me to remove all the Installshield Brand text at the left bottom of all dialogs. At first glance, it seems simple, as to just click and remove the Installshield text. But when I tried it, then it was really shocking to notice that the text I want to remove is disabled. Neither the line is enabled.

It was a real headache. Nowhere in the installshield help, nor in many forums, I failed to find any solution. This task was easy to do in Installscript MSI type projects, as there you are having that line and Installshield brand as a control, which you could delete from the control table.

Well, today I got a solution, which will hide Installshield brand, and the line adjoining it.

We will look one by one in different types of projects.

Installscript MSI:
In Installscript MSI type projects, first edit the dialog in which you want to Remove the Installshsield branding as shown below:

Then, goto Control table in Direct Editor, and remove the entry for ContorlId_7 as shown below:

Then make the width of the line same as the width of the dialog as shown below:

After editing the left coordinates and the width of the line, the design time preview should be like:

Basic MSI:
A Basic MSI dialog will look by default as:

Now we need a final dialog like: 

Now the question of concern is how could we achieve it. At first, it all seems to be as simple as selecting and deleting the control, but its not so similar to the steps performed in Installscript MSI project. Here we need to edit the "Control" table in Direct Editor.
By default values for Branding1 and Branding2 controls are shown below:

We need to edit attributes value for Branding1 from 3 to 2 and value for Branding2 from 65537 to 65536 as shown below:
Now, if you test the installer dialog then it will look like:


Now to put he line from left, we need to create a line control from the Installshield IDE controls toolbar as shown below:













Specify the left coordinates for the line control to 0 and width equal to that of dialog.

Finally the dialog will look like:

So, this way we can remove the Installshield brand name from the dialogs. Hope this post will be very helpful to you to customize your custom dialogs.

Tuesday, June 7, 2011

How to prevent application to show in ADD REMOVE Panel

In some cases, we need to hide the appearance of our product in Add or Remove Programs. 


Basic Msi Projects:
For Basic Msi Projects, we have a property named "ARPSYSTEMCOMPONENT". By setting this Windows Installer Property to 1 in the Property Manager, we could achieve this task. By setting this property, we simply suppress the display of our product in Add or Remove Programs. An end user can still remove our product by running the installation in maintenance mode or from the command line. 


Installscript Msi Projects:
To prevent our product from appearing in the Add or Remove Programs, select Yes for the Hide Add/Remove Panel Entry setting in the Releases view. 

Thursday, June 2, 2011

Running patch using admin execution level

Hi, I got a lot of appreciation for creating installer for my current project. After that project I was involved in some different projects. Almost after an year when I was shifted again to my last year installer project, at first glance it looks like to be little uncomfortable, to look into what modifications have been done in last one year.

Above all that I was told to create Patch installer. Ufff... again a lot of R&D's as I was working for the first time on a patch installer project. Well again I came out through with flying colours, as the patch installer was appreciated by the client.

But one concern was raised, that when we execute the full installer directly by just clicking it, it runs by using "Admin Execution Level", as it was done by using a setting in the installer project as shown in the screenshot below.







But there was not such setting when we look into Patch installer properties. I was told to look into how to execute Patch as an Administrator without using right click and selecting "Run as admin".

Well I find a solution after doing a lot of R&D. There is a tool named isremane.exe. This tool can be find at link http://support.installshield.com/kb/...isremanexe.zip


Open a command prompt window and run the following command:
isreman.exe /manifest:"C:\PathToNewManifest\setup.exe.manifest" "C:\PathToSetup\setup.exe"

for C:\PathToNewManifest\setup.exe.manifest use the file...
C:\program Files\InstallShield\2009\support\SetupExe.Admin.manifest

That should do it.


Saturday, May 14, 2011

Check and get list of existing AppPools and Websites on a machine for IIS 7.0


I have been using Installshield for so long, but tasks related to IIS 7.0 found to be most amazing, as it make me learn about IIS quite a lot. I got introduced with AppCmd.exe which is a single command line tool for managing IIS 7. AppCmd enables us to easily control the server without using a graphical administration tool and to quickly automate server management tasks without writing code.

Some of the things you can do with AppCmd:

  1. Create and configure sites, apps, application pools, and virtual directories
  2. Start and stop sites, and recycle application pools
  3. List running worker processes, and examine currently executing requests
  4. Search, manipulate, export, and import IIS and ASP.NET configuration

I had a requirement in one of my web project, for showing users a list of available App Pools and Web-sites for selection. Using vb-script found to be little uncomfortable, but AppCmd.exe makes my life easy.

Note: AppCmd.exe is located in the %systemroot%\system32\inetsrv\ directory. Because it is not path of the PATH automatically, you need to use the full path to the executable when executing commands like in "%systemroot%\system32\inetsrv\AppCmd.exe list sites". Alternatively, you can manually add the inetsrv directory to the path on your machine so that you can access AppCmd.exe directly from any location.

List of App Pools can be get by using command: "AppCmd.exe list apppool".







Similarly we can get the list of available websites: "AppCmd.exe list site".

We can take the output of the above commands in a text file, and can read the AppPool list. Similary we can do for Website.

Wednesday, May 11, 2011

Check existence of any program installed on a machine through registry

Hi, reading this post? It means you are really looking for how to check for existence of MS Office or any other program via script, or through registry. There are some standard locations in the registry editor, where you could manually search for existence of some program installed on the local machine. But not everyone is comfortable with it. Also, there are chances of any accidental deletion of any wrong key, if done by some immature user.

But when it comes to script, and especially from checking within the installer, then we had some options:

  1. System Search View: The system search view provides the Windows Installer capability to search for a particular file, folder, registry key, .ini file, or .xml file value on an end user's sytem prior to installation. this view is location in the left pane of the Installshield IDE, as shown in the image below:



    When you do right-click in the right pane as shown in the image below, a system Search Wizard opens which guides you to specify your search options for any Files, Folders, Registry Entries, and so on...




    You can specify your options according to your requirement.

  2. Installscirpt Code: Another option we have is through installscipt code. We need to specify a key to search in registry. There are some in-built installscript functions which can help you in accessing registry details. One of such function of our use at the moment is RegDBKeyExist(szKeyRoot) which checks for the key in the registr yspecified by parameter szKeyRoot.

    A typical example for your best understanding is given below which could check for existence of MS Office on the target machine.

         szKeyRoot="SOFTWARE\Wow6432Node\Microsoft\Office\Word\\";  \\key to search in registry 
        // get the registry value
        nResult = RegDBSetDefaultRoot( HKEY_LOCAL_MACHINE );
        if (RegDBKeyExist (szKeyRoot) < 0) then 
             return FALSE;
       else
             return TRUE;
       endif;

    Hope the above content will be helpful to you. In case you have some query, then please feel free to put some comments on this post, or reply to me.

Checking whether IIS 7.0 exist on a machine

Hi, This article will help to check if IIS 7.0 or lower version is installed on the target machine. There are several ways to check, both manually and through custom code by searching in registry.

  1. Go To Start -->  Run. Type inetmgr and press OK. If you get an IIS configuration screen, it is installed, otherwise it isn't.
  2. You can also check ControlPanel->Add Remove Programs, Click Add Remove Windows Components and look for IIS in the list of installed components.
To Reinstall IIS.

Control Pane -> Add Remove Programs -> Click Add Remove Windows Components Uncheck IIS box Click next and follow prompts to UnInstall IIS. Insert your windows disc into the appropriate drive. Control Pane -> Add Remove Programs -> Click Add Remove Windows Components Check IIS box Click next and follow prompts to Install IIS.

There are such situations in which you need to check IIS existence from the installshield using code, then you need to search for its registry on the target machine. For a helping deed, I am presenting an example below:


szKeyRoot="SOFTWARE\\Microsoft\\InetStp\\Components\\";     //key to search in registry
// Set the Default root
nResult = RegDBSetDefaultRoot( HKEY_LOCAL_MACHINE );
    
if (RegDBKeyExist (szKeyRoot) < 0) then 
  return FALSE;
else
    return TRUE;
endif;


The return value will determine whether IIS 7.0 exist or not.

MsiDoAction

MsiDoAction is used in Basic Msi type projects, where we are not having events like OnFirstUiBefore like we have in Installscript based projects. To call a custom action, we need to use this function.


The MsiDoAction function executes a built-in action, custom action, or user-interface wizard action.
Syntax
UINT MsiDoAction(
  __in  MSIHANDLE hInstall,
  __in  LPCTSTR szAction
);
Parameters:
hInstall [in]
Handle to the installation provided to a DLL custom action or obtained through MsiOpenPackage, MsiOpenPackageEx, or MsiOpenProduct.

szAction [in]
Specifies the action to execute.

Return Value:
ERROR_FUNCTION_FAILED
The function failed.

ERROR_FUNCTION_NOT_CALLED
The action was not found.

ERROR_INSTALL_FAILURE
The action failed.

ERROR_INSTALL_SUSPEND
The user suspended the installation.

ERROR_INSTALL_USEREXIT
The user canceled the action.

ERROR_INVALID_DATA
A failure occurred while calling the custom action.

ERROR_INVALID_HANDLE
An invalid or inactive handle was supplied.

ERROR_INVALID_HANDLE_STATE
The handle state was invalid.

ERROR_INVALID_PARAMETER
An invalid parameter was passed to the function.

ERROR_MORE_DATA
The action indicates that the remaining actions should be skipped.

ERROR_SUCCESS
The function succeeded.

The MsiDoAction function executes the action that corresponds to the name supplied. If the name is not recognized by the installer as a built-in action or as a custom action in the CustomAction table, the name is passed to the user-interface handler object, which can invoke a function or a dialog box. If a null action name is supplied, the installer uses the upper-case value of the ACTION property as the action to perform. If no property value is defined, the default action is performed, defined as "INSTALL".

Actions that update the system, such as the InstallFiles and WriteRegistryValues actions, cannot be run by calling MsiDoAction. The exception to this rule is if MsiDoAction is called from a custom action that is scheduled in the InstallExecuteSequence table between the InstallInitialize and InstallFinalize actions. Actions that do not update the system, such as AppSearch or CostInitialize, can be called.

Deffered Custom Actions

Deferred Execution Custom Actions:
Deferred custom action's purpose is to delay the execution of a system change to the time when the installation script is executed. This differs from a regular custom action, or a standard action, in which the installer executes the action immediately upon encountering it in a sequence table or in a call to MsiDoAction.

The installer does not execute a deferred execution custom action at the time the installation sequence is processed. Instead the installer writes the custom action into the installation script. The only mode parameter the installer sets in this case is MSIRUNMODE_SCHEDULED. See MsiGetMode for a description of the run mode parameters.

A deferred execution custom action must be scheduled in the execute sequence table within the section that performs script generation. Deferred execution custom actions must come after InstallInitialize and come before InstallFinalize in the action sequence.

Custom actions that set properties, feature states, component states, or target directories, or that schedule system operations by inserting rows into sequence tables, can in many cases use immediate execution safely. However, custom actions that change the system directly, or call another system service, must be deferred to the time when the installation script is executed.

Because the installation script can be executed outside of the installation session in which it was written, the session may no longer exist during execution of the installation script. This means that the original session handle and property data set during the installation sequence is not available to a deferred execution custom action.

Friday, May 6, 2011

How to read assembly version of a file.

Hello Friends, today I have a POC to work on i.e. get the version information of an assembly and to update it in a config file. This can be easily done in Dotnet, but in Installshield one should know the inbuilt function, which returns the numeric version information of the specified file.


Function Name: VerGetFileVersion
Syntax
VerGetFileVersion(szFileName,svVersionNumber)


Help:
Please refer to Installshield Help for more details.

Friday, March 4, 2011

Set MSI Property values through command line

Often we come across situations like how to update MSI properties during setup installation, which we may have hard coded at design time. It takes a lot of time to search in the help sections, or on Google, if the solution is needed in a go. Here is a way how to do that, which I had implemented a lot of times. Any better way is most welcomed.


Like your compiled .msi file, setup.exe can accept a number of command-line parameters.


With these parameters, we can specify data such as which language installer should run in, and whether to run setup.exe silently.


NOTE:
Command-line options that require a parameter must be specified with no space between the option and its parameter. For example, Setup.exe /v"ALLUSERS=2" is valid, while Setup.exe /v "ALLUSERS=2" is not. Quotation marks around an option's parameter are required only if the parameter contains spaces. If a path within a parameter contains spaces, you may need to use quotation marks within quotation marks, as in the following example: Setup.exe /v"INSTALLDIR=\"c:\My Files\"".



Ex:
setup.exe /v"MSIPROPERTY=Value"


where, MSIPROPERTY is any Msi Property setup inside the installer code.


More help on command line options

Uninstalling previous version during upgrade

 In my last project, I face a scenario where we need to uninstall previous version installed on the machine, before installing the new version. Although that requirement was later on pulled back, but since then I came to know how we can uninstall a product from within our code.


UninstallApplication:
UninstallApplication function launches the uninstallation that is specified by szUninstallKey.



Syntax:
UninstallApplication(szUninstallKey,szAdditionalCmdLine,nOptions)


Parameters: 
szUninstallKey --
Specifies the name of a subkey under the target registry's [root]\Software\Microsoft\Windows\CurrentVersion\Uninstall key; the function first
checks for the subkey under the root key HKEY_CURRENT_USER, and if it does not
find the subkey there, it checks under HKEY_LOCAL_MACHINE. For setups created
with InstallShield Professional 5.53 or earlier, this is typically the name of the application; for setups created with InstallShield Professional 6.0 or later, this is the application's product GUID including the surrounding braces ({}). Do not enter the product GUID of the current setup.


szAdditionalCmdLine:
Specifies any additional command line arguments that you want to pass to the uninstallation. You do not need to specify command line arguments that are already specified in szUninstallKey's UninstallString value's data.


nOptions:
Specifies additional options. You can specify any option that is supported by LaunchApplication


Example:

RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
sExeRegistryPath="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\InstallShield_{D0BAAF19-362E-48C7-8640-43B66DD381E5}";
if (RegDBKeyExist(sExeRegistryPath) = 1) then
szUninstallKey = "";
szUninstallKey = "InstallShield_{D0BAAF19-362E-48C7-8640-43B66DD381E5}";
//Specified for silent uninstallation
szAdditionalCmdLine="/uninst";
UninstallApplication ( szUninstallKey, szAdditionalCmdLine, LAAW_OPTION_WAIT||LAAW_OPTION_MINIMIZED);


abort;
endif;

Monday, January 24, 2011

Read Write XML data

In Installshield projects, often we need to manipulate XML, either by reading specific values, or updating some values. For e.g. in case of configs. The examples mentioned below will be very handy when dealing with XML's.
Reading XML data:
// Creating an object for MsXML2 for xml manipulation
set oDoc = CoCreateObject("Msxml2.DOMDocument");
oDoc.setProperty("SelectionLanguage", "XPath");


// load the XML document into memory
if oDoc.load(strFileName) then


// Set XPath in XMl file to work on...
szXPath = "/configurations/setting[@name='AuthenticationAuthService']";


// This will return the default value for AuthenticationAuthService
sAuthServerURL = ReadDefaultConfigValues(szXPath,"default",oDoc);


Function: The below function is a custom action which will return the values from the XML tag elements.


function STRING ReadDefaultConfigValues(szXPath,szkey,oDoc)
OBJECT oNode;
begin
set oNode = oDoc.documentElement.selectSingleNode(szXPath);
if(gbConfigImported==FALSE) then
return oNode.attributes.getNamedItem(szkey).value;
else
return oNode.text;
endif;
end;
-------------------------------
Writing/saving XML data
set oDoc = CoCreateObject("Msxml2.DOMDocument");
oDoc.setProperty("SelectionLanguage", "XPath");


// set up variable with fullpath to xml config file
szConfigFile = gWIN_INSTALLDIR^"PaginationService\\TranscendBTG4.PaginationService.exe.config";


Configure_ConfigFile(szConfigFile,"/configuration/connectionStrings/add[@name='TranscendConnectionString']",strConnectionString,"connectionString",oDoc);


// Save the XML Changes
oDoc.save(szConfigFile);


Function: The below function is a custom action which will save/update the values from the XML tag elements.


function Configure_ConfigFile(szConfigFile,szXPath,strValue,key,oDoc)
OBJECT oNode;
begin
// load the XML document into memory
if oDoc.load(szConfigFile) then
//Set the XPath in the XML
set oNode = oDoc.documentElement.selectSingleNode(szXPath);
oNode.attributes.getNamedItem(key).value = strValue;
endif;
end;