Skip to main content link. Accesskey S
  • Anonymous
  • Log on
  • Help
  • IBM logo
  • Lotus Quickr wiki
  • All Wikis
  • Home
  • Community Articles
  • Product Documentation
  • Learning Center


Search

Advanced Search

Categories

Tag Cloud

  • 2010 Quickr 8.5 Customer Day
  • 8.0
  • 8.1
  • 8.1.1
  • 8.2
  • 8.5
  • administering
  • administrators
  • API
  • atom
  • authentication
  • best practices
  • best_practices
  • blogs
  • calendar integration
  • chat
  • clustering
  • configuration
  • configuring
  • Connections
  • Connectors
  • Content Integrator
  • customization
  • customizing
  • customizing_quickr
  • demo
  • deploying
  • deployment
  • Development
  • Document
  • document_libraries
  • Domino
  • draft
  • ECM
  • education
  • email
  • enablement
  • events
  • Feed
  • FileNet
  • folder
  • getting started
  • getting_started
  • installation
  • installing
  • integrating
  • introducing
  • key file
  • ldap
  • Library
  • lotusphere
  • LTPA
  • Masterclass
  • Media Gallery
  • media_Domino
  • media_Portal
  • migrating
  • migration
  • mml
  • nodes
  • notes
  • P8
  • performance
  • Places
  • Portal
  • profiles
  • proxy
  • qpconfig.xml
  • QRD85 Enablement
  • QuickPlace
  • Quickr
  • Quickr 8.5
  • Quickr Domino 8.2 Masterclass
  • Quickr Domino 8.5
  • Quickr Domino 8.5.1
  • Quickr Domino8.5
  • Quickr J2EE 8.1.1 Masterclass
  • Quickr_customization
  • Quickr_Domino_8.5
  • quickrD
  • QuickrJ
  • REST
  • Sametime
  • security
  • SiteMinder
  • SPNEGO
  • SSL
  • SSO
  • TAM
  • templates
  • test_infrastructure
  • theme
  • themes
  • tips
  • troubleshooting
  • upgrading
  • video
  • web_seminar
  • webservices
  • xml_node
InformationInformation
You are currently viewing machine translated content. IBM translation might be available. Click IBM Translated Product Documentation to see what is available.X


Home > Lotus Quickr Connectors > Developing a 32-bit installer to install plug-ins into 64-bit applications based on InstallShield
Rate this article 1 starRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars

Developing a 32-bit installer to install plug-ins into 64-bit applications based on InstallShield 

expanded Abstract
collapsed Abstract
This article provides some best practices on developing a 32-bit installer to support 64-bit applications based on InstallShield. To illustrate these best practices, we explain the differences between 32-bit Microsoft® Windows® and 64-bit Windows, review the properties of InstallShield and Windows APIs, and use the IBM® Lotus® Quickr® connectors installer (hereafter referred to as qkrconn.exe) as an example to show how to achieve it.
ShowTable of Contents
HideTable of Contents
  • 1 Introduction
    • 1.1 Compatibility
    • 1.2 Registry
    • 1.3 File system
    • 1.4 Access control
  • 2 Detecting the bitness of a Windows operating system
  • 3 Registering both 32- and 64-bit DLLs manually
  • 4 Unregistering DLLs when removing an application
  • 5 Conclusion
  • 6 Resources
  • 7 About the authors

Introduction


Lotus Quickr connectors provide an easy way to contribute and access content. They are plug-ins into commonly used desktop applications such as Lotus SymphonyTM, Lotus Notes®, Lotus Sametime®, Microsoft Windows Explorer and Microsoft Office. Users can choose the suitable connector based on the desktop application they use most often in their routine work.

InstallShield is a software tool for creating installers or software packages. The qkrconn.exe file is an InstallShield-based Windows installer package, containing all the information that the Windows Installer requires to install or uninstall Lotus Quickr connectors and to run the setup user interface.

Comparing 32-bit Windows XP and 64-bit Windows 7
First let's discuss how the 32-bit Windows XP and 64-bit Windows 7 operating systems differ.

Compatibility


Nearly all 32-bit applications are able to run on 64-bit Windows. This allows both 32- and 64-bit versions of the same applications to be installed side-by-side on 64-bit Windows, without risk of overwriting one another’s files or inadvertently accessing the wrong versions of the same library.

Under 64-bit Windows, 32-bit applications run on top of an emulation of 32-bit Windows called Windows on Windows 64-bit (WOW64) as shown in figure 1. WOW64 intercepts all operating system calls made by a 32-bit application.

For each operating-system call made, WOW64 generates native 64-bit system calls, converting 32-bit data structures into 64-bit aligned structures. The appropriate native 64-bit system call is passed to the operating system kernel, and any output data from the 64-bit system call is translated into a format appropriate for the calling application before being passed back.

Figure 1. 32-bit application running on WOW64


Although it is possible for a 32-bit installer to run on 64-bit Windows, as a plug-in's installer, it is still not enough to support a 64-bit application without 64-bit versions of libraries. So, to support 64-bit applications with a 32-bit installer, the 32-bit and 64-bit versions of the same libraries must exist side-by-side in the same component of InstallShield. For qkrconn.exe, to support 64-bit Windows Explorer, the 64-bit DLLs should be included in it.

Registry


On 64-bit Windows, the Registry is divided into 32- and 64-bit keys. Many of the 32-bit keys have the same names as their 64-bit counterparts, and they are redirected from HKEY_LOCAL_MACHINE\Software to HKEY_LOCAL_MACHINE\Software\WOW6432Node.

WOW64 uses the Registry redirector to intercept 32- and 64-bit registry calls to their respective logical registry views and map them to the corresponding physical registry location.

For example, when you install Lotus Quickr connector on 64-bit Windows 7, the WOW64 intercepts registry calls to HKEY_LOCAL_MACHINE\Software that are made by qkrconn.exe, and then redirects them to the HKEY_LOCAL_MACHINE\Software\WOW6432node sub key. Registry calls won't be redirected if they are made by 64-bit applications accessing the HKEY_LOCAL_MACHINE\Software registry sub key.

File system


On 64-bit Windows, there are separate folders for program and operating-system files for 32- and 64-bit applications. The file system redirector ensures that requests from 32-bit applications to open files in C:\Program Files or C:\WINDOWS\SYSTEM32 are redirected to the appropriate 32-bit directories C:\Program Files(x86) and C:\WINDOWS\SysWOW64.

For Lotus Quickr connectors, the default installation path is "C:\Program Files (x86)\IBM\Places Connectors". Both 32- and 64-bit libraries are installed into this directory, and the Regsvr32.exe used by the qkrconn.exe is in "C:\WINDOWS\SysWOW64".

All these tasks are done transparently for 32-bit applications by WOW64, which, when intercepting calls to the operating system, detects references to file paths and registry keys, and maps them accordingly.

Access control


User Account Control (UAC) is another way in which Windows XP and Windows 7 differ. UAC aims to improve the security of Windows by limiting applications to standard user privileges until an administrator authorizes an increase or elevation. So there is an issue with administrator privileges of which developers should be aware, which we will discuss later.

Detecting the bitness of a Windows operating system


Since we have the 32- and 64-bit versions of the same libraries, we need to detect the bitness of Windows to determine which version of the DLLs should be registered or unregistered. Microsoft provides the method shown in listing 1.

Listing 1. Code to detect bitness

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
BOOL Is64BitOS() {
#if defined(_WIN64)
	return TRUE;   // 64-bit programs run only on Win64
#elif defined(_WIN32)
	// 32-bit programs run on both 32-bit and 64-bit Windows
	BOOL f64bitOS = FALSE;
	return (SafeIsWow64Process(GetCurrentProcess(), &f64bitOS) && f64bitOS);
#else
	return FALSE;  // 64-bit Windows does not support Win16
#endif
}

BOOL WINAPI SafeIsWow64Process(HANDLE hProcess, PBOOL Wow64Process) {
	if (fnIsWow64Process == NULL) {
		HMODULE hModule = GetModuleHandle(L"kernel32.dll");
		if (hModule == NULL) {
			return FALSE;
		}

		fnIsWow64Process = reinterpret_cast<LPFN_ISWOW64PROCESS>(
			GetProcAddress(hModule, "IsWow64Process"));
		if (fnIsWow64Process == NULL) {
			return FALSE;
		}
	}
	return fnIsWow64Process(hProcess, Wow64Process);
}


Registering both 32- and 64-bit DLLs manually


If the 32-bit installer needs only to support 32-bit Windows, we can use the Self-Register property that is by provided InstallShield to register 32-bit DLLs automatically during installation. We don't need to write extra codes.

However, we cannot use the Self-Register property to register 64-bit DLLs, or else an error will occur during installation because the installer is 32-bit. For qkrconn.exe, if we use the Self-Register property, the error message in figure 2 will display during installation.

Figure 2. Error message when registering 64-bit DLL using Self-Register property


So we need register both 32- and 64-bit DLLs manually, meaning that we must use a command line in our code to register them. Regsvr32.exe is a command-line utility in Windows operating systems and is used to register and unregister DLLs and ActiveX controls in the Windows Registry.

We can use it to register or unregister applications; for example, use regsvr32 my_file.dll to register modules passed on the command line.

Also we could use Msiexec.exe to register or unregister DLLs. Msiexec.exe belongs to the Windows Installer and is used to interpret installation packages and install products on target systems. For example, msiexec /z my_file.dll is used to unregister modules passed on the command line.

There are two versions of Regsvr32.exe and Msiexec.exe. Files in the System32 folder are the 64-bit version, and the Syswow64 folder contains the 32-bit versions of Regsvr32.exe and Msiexec.exe.

For connectors, we use Regsvr32.exe to register or unregister our DLLs using the ShellExecute function. Because of the WOW64, the Regsvr32.exe we use is a 32-bit version. The register code looks like this:

ShellExecute( handle, NULL, "regsvr32.exe", "/s my_file.dll", NULL, SW_SHOWNORMAL );

When we use Regsvr32.exe to register or unregister the DLL files, the Administrator privilege is needed; otherwise it will fail to register or unregister the DLLs (see figures 3 and 4).

Figure 3. Error when fail to register DLL file on Windows 7


Figure 4. Error when fail to register DLL file on Windows XP


To locate the DLL files and perform registration tasks with elevated privileges, we need to create a custom action in InstallShield for calling a registration function and schedule it as Deferred Execution in System Context. It is a special sort of deferred custom action that is used to perform tasks with elevated privileges.

However, the deferred custom action runs in a separate process and only has access to some of the built-in Windows Installer properties, that is, CustomActionData, ProductCode, and UserSID. If we want a custom action to access any other properties, such as installdir, during deferred execution, we can pass them as CustomActionData by scheduling an immediate set-a-property type of custom action to set a property that matches the name of the custom action.

The value of this property is then available in the CustomActionData property within the deferred custom action. The registration function in Visual Studio would look like that shown in listing 2.

Listing 2. Code for registration function

APP_API APPRegisterDlls( MSIHANDLE hInstall ) {
	TCHAR szPath[255];
	TCHAR szDllToRegister[255];
	DWORD cchPath = sizeof(szPath)/sizeof(TCHAR);

	MsiGetCustomActionData(hInstall, TEXT("INSTALLDIR"), szPath, &cchPath);

	BOOL Is64bit = Is64BitOS();
	TCHAR *DLLName;

	if(Is64bit==TRUE) {
		DIViewName= L"my_file64.dll";
	}else {
		DIViewName= L"my_file.dll";

	}

	wsprintf(szDllToRegister,L"/s \"%s%s\"", szPath,DIViewName);
	DWORD exRC = (DWORD)ShellExecute( HWND_DESKTOP, 0, L"regsvr32.exe", szDllToRegister, 0, SW_SHOWDEFAULT );

	return ERROR_SUCCESS;
}  

The MsiGetCustomActionData function is used to retrieve the INSTALLDIR that we set in the immediate custom action.

Unregistering DLLs when removing an application


Because we register both 32- and 64-bit DLLs manually, a problem due synchronous processes could occur when we use the ShellExecute function to unregister DLLs directly when removing the application from Control Panel. Specifically, since the ShellExecute function launches a new process to run the unregister command, the DLL files could be deleted before unregistering them.

To solve this problem, the main process needs to wait until the deferred custom action has finished running (see figure 5). So we use the ShellExecuteEx and WaitForSingleObject functions instead of the ShellExecute function. The WaitForSingleObject function lets the concurrent process wait until the specified object, such as Process, is in the signaled state.

Figure 5. Workflow between two processes


Listing 3 shows an example of this.

Listing 3. Example of WaitForSingleObject function

SHELLEXECUTEINFO ShExecInfo;
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = L"regsvr32.exe";
ShExecInfo.lpParameters = L"/s /u my_file.dll”;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;

ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);

We can also use the CreateProcess function (see listing 4).

Listing 4. Example CreateProcess function

PROCESS_INFORMATION pi;
STARTUPINFO si;
	
// init the process parameters
ZeroMemory(&si, sizeof(si));
StartupInfo.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
	
// start the process
CreateProcess("c:\\winnt\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);

// close the handle
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);


Retrieving process information from 64-bit Windows under WOW64
The usual way to retrieve the process information from a 32-bit Windows system is as follows:
  1. Get the list of process identifiers by using the EnumProcesses function.
  2. Call the OpenProcess function to obtain the process handle.
  3. Call the EnumProcessModules function to obtain the module handles.
  4. Call the GetModuleBaseName function to, for example, obtain the name of the executable file.

In our project, however, when we followed the above steps, the 32-bit installer failed to get process information from 64-bit Windows 7 because the EnumProcessModules function doesn’t work on 64-bit windows.

Although the EnumProcessModulesEx function can retrieve handles for modules on 64-bit Windows, it provides the same results as the EnumProcessModules function if it is called by a 32-bit application running under WOW64.

There is still one way to retrieve process information when a 32-bit application is running under WOW64, and that is Windows Management Instrumentation (WMI). This WMI service provides the infrastructure for management data and operations on Windows-based operating systems and can be used in all Windows-based applications. For more information about creating applications for WMI, refer to the article, “Getting WMI Data from the Local Computer.”

Conclusion


Although this article discusses only some of the points that must be addressed, our hope is that, by describing the more common scenarios, we have helped you understand how to best support 64-bit applications with 32-bit installer in your side.

Resources


Lotus Quickr Connectors product page:
http://www-01.ibm.com/software/lotus/products/quickr/connectors.html

MSDN article on WOW64, “Running 32-bit Applications:”
http://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx

MSDN article, “User Account Control:”
http://msdn.microsoft.com/en-us/library/aa511445.aspx

MSDN article, “Windows Management Instrumentation on WMI:”
http://msdn.microsoft.com/en-us/library/aa394582(v=vs.85).aspx

About the authors


De Liang Jiang is a member of the Lotus Connections Install team for Lotus Connections install development. You can reach him at dljiang@cn.ibm.com.

Hao Jie Hang is a member of the Lotus Quickr connectors Install team for Team connectors install development. You can reach him at hjhaojie@cn.ibm.com.

Hai Yang Liu is a member of the Lotus Quickr connectors Install team for Files connectors install development. You can reach him at hiayangl@cn.ibm.com.


expanded Article information
collapsed Article information
Category:
Lotus Quickr Connectors
Tags:
install

This Version: Version 4 February 22, 2011 1:01:58 PM by Leslie Gallo  IBMer

expanded Attachments (0)
collapsed Attachments (0)

 


expanded Versions (4)
collapsed Versions (4)
Version Comparison     
Version Date Changed by               Summary of changes
This version (4) Feb 22, 2011 1:01:58 PM Leslie Gallo  
2 Feb 22, 2011 1:00:41 PM Leslie Gallo  
1 Feb 22, 2011 12:48:20 PM Leslie Gallo  
1 Feb 22, 2011 12:55:06 PM Leslie Gallo  
expanded Comments (0)
collapsed Comments (0)
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedSubscribe to RSSHelpAbout
  • All Lotus and WebSphere Portal wikis
  • IBM developerWorks
  • IBM Software support
  • IBM Social Business User Experience Blog
  • IBMSocialBizUX on Twitter
  • IBMSocialBizUX on Facebook
  • Lotus product forums
  • IBM Social Business UX Blog
  • IBM Collaboration Solutions
  • Recently added feedRecently added
  • Recently edited feedRecently edited
  • Recently added comments feedRecently Added Comments
  • Wiki Help
  • Forgot user name/password
  • Wiki design feedback
  • Content feedback
  • About the wiki
  • About IBM
  • Privacy
  • Contact IBM
  • IBM Terms of use
  • Wiki terms of use