Sunday, May 13, 2012

Installshield Build Error Code 0

I was facing this issue with Installshield 2012 SP1. I had installed this product with AdminStudio 11.

When I converted the MSI to .ism project through Installshield and then tried to build it back to MSI, I always got this error code 0.

I could not find any documentation for this online so wrote back to Installshield Customer Support and they came up with this work around. Hope this will help you if you are facing this similar issue with your product. Do let me know by commenting if this has helped you. Just want to know how many people are affected by this,


Within the .ism project:

Go to the Direct Editor under the Additional Tools section.
Select the InstallShield table.
Change the SchemaVersion property from 772 to 771.
Save, close, and reopen the project.
InstallShield will prompt asking if you want to upgrade the project.
Click Yes to upgrade the project.

You should now be able to build the project without error.


Apprantly this is the issue with this release of the product only and it has been fixed with the later releases.

Friday, April 27, 2012

VBScript to Determine 32-bit or 64-bit machine

Often we come across a situation where we need to see the Operating system bit information and then install application or do any customization. Here is a script which I use for this purpose:


'===============================================================

Const HKEY_LOCAL_MACHINE = &H80000002
'Lines to get the computer Name

Set wshShell = WScript.CreateObject( "WScript.Shell" )
strComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )

 
'===============================================================
'To check whether the OS is 32 bit or 64 bit of Windows 7
'===============================================================

'Lines to detect whether the OS is 32 bit or 64 bit of Windows 7

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerName & "\root\default:StdRegProv")

  strKeyPath = "HARDWARE\DESCRIPTION\System\CentralProcessor\0"

  strValueName = "Identifier"

oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'===============================================================

'Checking Condition whether the build is 64bit or 32 bit

  if (instr(strValue,"64")) then

'Perform functions for 64-bit OS.
End If

if (instr(strValue,"x86")) then

'Perform functions for 32-bit OS
 End If
'===============================================================

Thursday, April 19, 2012

VBScript to determine Root Drive

As per best practices we should not hard code the Root Drive in our package. If your package goes to multiple machines having different Root Drives, then you can use this simple VBScript in your package as Custom Action and it will set the Root Drive automatically for that machine.
This script picks up the Root Drive from where Program Files folder is installed.

Set oshell=CreateObject("Wscript.shell")
prog=oshell.ExpandEnvironmentStrings("%ProgramFiles%")
vletter=Split(prog,":")
dletter=vletter(0) & ":\"
session.property("ROOTDRIVE")=dletter

Wednesday, April 11, 2012

Installation and Uninstallation of MSU in silent mode

MSU are the Microsoft Update files.
You can easily install the MSU file silently without reboot with the following command line:


wusa.exe Windows6.1-KB123456-x86.msu /quiet /norestart

To Uninstall it Silently you need to follow this simple procedure:

1) Run this command:
expand c:\temp\Windows6.0-KB123456-x86.msu –F:Windows6.0-KB123456-x86.xml c:\temp

2) This will create an XML file in temp folder as per the name above.
Edit this xml in notepad.

3)Find the assemblyidentity tag. Then, note the values of the following attributes:
  • The name attribute
  • The publickeytoken attribute
  • The processArchitecture attribute
  • The version attribute
4) Use the below command to uninstall the MSU from your machine.
start /w pkgmgr /up:name~publickeytoken~processArchitecture~~version

Note: The variables above need to be replaced by the vaules you have copied in step 3.

Wednesday, April 04, 2012

VBScript to copy file and Powershell Script to copy file

VBScript to copy file:

dim filesys, oShell
Set filesys = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
sup = oShell.ExpandEnvironmentStrings ("%APPDATA%")
des = oShell.ExpandEnvironmentStrings ("%ProgramFiles(x86)%")
destfile= sup & "\AR System\HOME\AR"
sourcefile= des & "\AR System\User\AR"
If filesys.FileExists(sourcefile) Then
   filesys.CopyFile sourcefile, destfile
End If


Powershell Script to copy file:

$SourceFile = "c:\foo\Test.txt"; 
$NewFile    = "c:\foo\Test2.txt"; 
 
# Now - check to see if $Sourcefile exists, and if so, 
# copy it to $newfile  
if ([System.IO.File]::Exists($SourceFile))  { 
   [System.IO.File]::Copy($SourceFile, $NewFile) 
   "Source File ($SourceFile) copied to ($newFile)" 

else { 
"Source file ($Sourcefile) does not exist." 
}

Monday, March 26, 2012

Creating a SendTo Shortcut through MSI

If you want to create a SendTo shortcut through MSI, then if you just add the shortcut in MSI in SendTo folder, it will not work. Even if you get the shortcut there in every user profile, still it will not work. To make a SendTo shortcut, you need to create it on the fly, which means that shortcut should be created from original exe. To solve this issue for one of my application, WinSCP, I wrote the below VBScript and placed it in %ALLUSERPROFILE%\WinSCP folder. Then I created an Active setup to call this VBScript.


Set Shell = CreateObject("WScript.Shell")
ShortcutPath = Shell.SpecialFolders("SendTo")
Set link = Shell.CreateShortcut(ShortcutPath & "\WinSCP (for upload).lnk")
link.Arguments = "/upload"
link.Description = "WinScp"
link.HotKey = ""
link.IconLocation = "C:\Program Files (x86)\WinSCP\WinSCP.exe,0"
link.TargetPath = "C:\Program Files (x86)\WinSCP\WinSCP.exe"
link.WindowStyle = 3
link.WorkingDirectory = "C:\Program Files (x86)\WinSCP"
link.Save


To delete this SendTo shortcut, I wrote another script and added an active setup registry key through CA during Remove sequence to run this script.


dim filesys
Set filesys = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("WScript.Shell")
sup = oShell.ExpandEnvironmentStrings ("%APPDATA%")
WinSCPlnk= sup & "\Microsoft\Windows\SendTo\WinSCP (for upload).lnk"
If filesys.FileExists(WinSCPlnk) Then
filesys.DeleteFile WinSCPlnk
End If


Also remember to make the above component as permanent, because you do not want to delete this vbs file at uninstall of application.

Sunday, March 18, 2012

VBScript to Kill a Process

This worked great for me. Just use as function and kill as many processes as you like.

KillProc "abc.exe"
Sub KillProc( myProcess )
    Dim blnRunning, colProcesses, objProcess
    blnRunning = False
    Set colProcesses = GetObject( _
                       "winmgmts:{impersonationLevel=impersonate}" _
                       ).ExecQuery( "Select * From Win32_Process", , 48 )
    For Each objProcess in colProcesses
        If LCase( myProcess ) = LCase( objProcess.Name ) Then
            ' Confirm that the process was actually running
            blnRunning = True
            ' Get exact case for the actual process name
            myProcess  = objProcess.Name
            ' Kill all instances of the process
            objProcess.Terminate()
        End If
    Next
    If blnRunning Then
        Do Until Not blnRunning
            Set colProcesses = GetObject( _
                               "winmgmts:{impersonationLevel=impersonate}" _
                               ).ExecQuery( "Select * From Win32_Process Where Name = '" _
                             & myProcess & "'" )
            WScript.Sleep 100 'Wait for 100 MilliSeconds
            If colProcesses.Count = 0 Then 'If no more processes are running, exit loop
                blnRunning = False
            End If
        Loop
      End If
End Sub

Monday, March 12, 2012

VBScript to enable "Use this connection's DNS Suffix in DNS registration" in IPV4

I have written this below VBScript to enable "Use this connection's DNS Suffix in DNS registration" in IPV4 Advanced Settings.

For Desktop adaptor, this (to enable "Use this connection's DNS Suffix in DNS registration" in IPV4) can be fixed by changing the registry value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\NetworkInterfaceID\RegisterAdapterName to 1

Here NetowrkInterfaceID is a unique ID for every user and this can be obtained from "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\8\ServiceName" key.

The issue is there can be multiple Network adaptors connected to the machine like Network adaptor for Desktop, Wireless Adaptor, VMware adaptor etc and they all are stored under different hive, like 8, 12, 14 etc. Hence I have written a script which will check for all this and will change the value for all adaptors. If you want for only one particular adaptor, you can modify the script accordingly.

Following VB Functions can be independently picked too:
1) Read Registry
2) Registry Key exists
3) iteration in VBScript (For Loop)
4) Write Registry key.


On Error Resume Next

Dim NetworkInterfaceID, RegKeyValue, Temp

'HKEY_CURRENT_USER = HKCU
 'HKEY_LOCAL_MACHINE = HKLM
 'HKEY_CLASSES_ROOT = HKCR
 'HKEY_USERS = HKEY_USERS
 'HKEY_CURRENT_CONFIG = HKEY_CURRENT_CONFIG
Function KeyExists(key)
    Dim objShell
    On Error Resume Next
    Set objShell = CreateObject("WScript.Shell")
        objShell.RegRead (key)
    Set objShell = Nothing
    If Err = 0 Then KeyExists = True
End Function

For i = 0 to 20
  
RegistryKeyName = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\" & i & "\"
If KeyExists(RegistryKeyName) Then
Reg= RegistryKeyName + "ServiceName"
NetworkInterfaceID = ReadReg(Reg)
RegKeyValue = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\" + NetworkInterfaceID + "\RegisterAdapterName"
WriteReg RegKeyValue, 1 ,"REG_DWORD"
End If
Next
 'WScript.Echo Temp
 Function WriteReg(RegPath, Value, RegType)
       'Regtype should be "REG_SZ" for string, "REG_DWORD" for a integer,…
       '"REG_BINARY" for a binary or boolean, and "REG_EXPAND_SZ" for an expandable string
       Dim objRegistry, Key
       Set objRegistry = CreateObject("Wscript.shell")

      Key = objRegistry.RegWrite(RegPath, Value, RegType)
       WriteReg = Key
 End Function
 Function ReadReg(RegPath)
       Dim objRegistry, Key
       Set objRegistry = CreateObject("Wscript.shell")

      Key = objRegistry.RegRead(RegPath)
       ReadReg = Key
 End Function

Wednesday, February 22, 2012

How to make an MSI with some files compressed in Cabinet file and other uncompressed outside the MSI

This is a very interesting feature in MSI and I would like to explore and explain this for your knowledge and benefit.

Word Count generally known as Word Count Summary property. This is a mandatory Summary property in MSI and can be changed from your WSI. Please note that this property is not in Property table but is in Summary table.
This property has a different meaning for MSI, Transforms and Patch.
This property is a bit feild.
There are 4 bits which can be set or unset as in 0 or 1. eg. 01
Here is the description for these bits:
---------------------------------------------------------------------------------
Bit 0
0 Long file names.
1 Short file names.

---------------------------------------------------------------------------------
Bit 1
0 Source is uncompressed.
2 Source is compressed.

---------------------------------------------------------------------------------
Bit 2
0 Source is original media.
4 Source is a administrative image created by an administrative installation.
---------------------------------------------------------------------------------
Bit 3
0 Elevated privileges can be required to install this package.
8 Elevated privileges are not required to install this package.

Available starting with Windows Installer version 4.0 and Windows Vista or
Windows Server 2008.
---------------------------------------------------------------------------------

Here is what you get when you combine these values:

Value=0
means Original source is using long file names. Matches tree in Directory
Table. Elevated privileges can be required to install this package.

Value=1 means Original source is using short file names. The file structure
Matches tree in Directory Table. Elevated privileges can be required to install
this package.

Value=2 means Compressed source files using long file names. Matches cabinets and
files in the Media Table. Elevated privileges can be required to install this
package.

Value=3 means Compressed source files using short file names. Matches cabinets
and files in the Media Table. Elevated privileges can be required to install this
package.

Value=4 means you are installing an Administrative image using long file names.
Matches tree in Directory Table. Elevated privileges can be required to install
this package.

Value=5 means you are installing an Administrative image using short file names.
Matches tree in Directory Table. Elevated privileges can be required to install
this package.

Value=8
means Elevated privileges are not required to install this package. Use
this value when Authoring Packages without the UAC Dialog Box.
Available starting with Windows Installer version 4.0 and Windows Vista or
Windows Server 2008.

Now if you set the Bit 1 which means that the package is marked as compressed,
the Windows Installer only installs files located at the root of the source and
not in the tree like directory structure. In this case even the files marked as
Uncompressed in the File table must be located at the root of the source
directory of your MSI so that they can be installed.
Now to make a package that has both a cab file (compressed files) and
uncompressed files that match the tree in Directory table, you need to mark the
package as uncompressed by leaving bit 1 unset, that is a value of 0 in the Word
Count Summary Property and then you need to set the File Attribute to compressed
file (value of 16384 to be added to the current value of file attribute) in the
attribute column of file table for each file which is in Cabinet file.

Transforms:

In Transform you should not try and experiment with this property because in
Transforms this property should be always Null.
Patches:
In Patches the value of this property determines the minimum Windows Installer
version required to install the patch.
Value=1 which is the default value, means that MSPATCH was used to create the
Patch
Value=2 means a minimum version of Windows Installer 1.2 is required for patch to
be applied.
Value=3 means a minimum version of Windows Installer 2.0 is required for patch to
be applied.
Value=4 means a minimum version of Windows Installer 3.0 is required for patch to
be applied.
Value=5 means a minimum version of Windows Installer 3.1 is required for patch to
be applied.

Hope this new information will be helpful to you in designing your MSI in a
better way

Monday, January 23, 2012

Packaging Mozilla Firefox

Most people dread while packaging Mozilla Firefox application and mostly try to make a silent installation of it. I was recently given task to package the latest Mozilla Firefox application.
The same procedure can be used for version 10.0.1, 11, 12 and 13, 14 and 15 as well as I have tried and it works fine for all of these.
I would like to share here how I could easily package it. Also by this method you will be able to do Proxy server settings.
First step is to do a Setup capture of the source exe which can be downloaded from Mozilla’s website. Take care that you do not have to launch the application after the installation is completed.
Second Step is to copy 3 files as stated below. You can add these files in your .wsi directly after the setup capture. These 3 files will solve all your issues.

1. Mozilla.cfg: This file needs to be added to "%programfiles%\Mozilla Firefox\" folder and should have this content:

//Firefox Default Settings
// set Firefox Default homepage
pref("browser.startup.homepage","http://your.intranet.com");
// disable default browser check
pref("browser.shell.checkDefaultBrowser", false);
// disable application updates
pref("app.update.enabled", false)
// disables the 'know your rights' button from displaying on first run
pref("browser.rights.3.shown", true);
// disables the request to send performance data from displaying
pref("toolkit.telemetry.prompted", 2);
pref("toolkit.telemetry.rejected", true);
//Firefox Default Settings
//set proxy server settings, choose whatever is required by your organization
pref("network.proxy.ftp", "your.proxy.server");
pref("network.proxy.ftp_port", 8080);
pref("network.proxy.gopher", " your.proxy.server ");
pref("network.proxy.gopher_port", 8080);
pref("network.proxy.http", " your.proxy.server ");
pref("network.proxy.http_port", 8080);
pref("network.proxy.no_proxies_on", "localhost, 127.0.0.1, *.server.local");
pref("network.proxy.type", 1);
pref("network.proxy.share_proxy_settings", true); // use the same proxy settings for all protocols


2. local-settings.js: This file needs to be added to "%programfiles%\Mozilla Firefox\defaults\pref" folder and should have this content:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "mozilla.cfg");

3. override.ini : This file needs to be added to “%programfiles%\Mozilla Firefox\” folder and should have this content:

[XRE]
EnableProfileMigrator=false


It is just this simple you can now just remove the Desktop shortcut in your .wsi file and compile it to .msi file.