My blog has moved!

You should be automatically redirected in 6 seconds. If not, visit
http://kavachai.com
and update your bookmarks.

Thursday, October 22, 2009

Updating Application That Has Custom Actions in Setup.dll

Recently I was creating installer for application that is suppose to be updated regulary. Also cab installer for this application used setup.dll to perform custom actions during install/uninstall.

Since cab installer doesn't have "update" feature installing update is done as a sequence: uninstall_old > install_new. Calls to setup.dll will be as follows:
  1. Install_Init() from new setup.dll is called with fFirstCall=true and fPreviouslyInstalled=true.
  2. Old installation is removed. This leads to calls to Uninstall_Init() and Uninstall_Exist() from old setup.dll (which is stored in \windows\AppMgr).
  3. Install_Init() from new setup dll is called with fFirstCall=false and fPreviouslyInstalled=false.
  4. New files are extracted by cab installer.
  5. Install_Exist() is called.
To control updating process I needed to use some kind of a marker that will be available at all of those steps.
Originally I tried to use named Mutex (mainly because it is an in-memory object), but for some reason it didn't work as expected. So I considered key in registry and a file. Creating/removing file just to use it as a marker is not very good idea and my final solution was to use a key in registry:
#include <windows.h> 
#include <string.h>

///////////////////////////////////////////////////////////
// Methods to work with marker.

void SetInstallingStartFlag() {
HKEY hKey = NULL;
DWORD dwDisposition;
if (::RegCreateKeyEx(HKEY_CURRENT_USER, _T("\\SOFTWARE\\MySoftwareInstall"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) {
::RegCloseKey(hKey);
}
}
void RemoveInstallingStartFlag() {
HKEY hKey = NULL;
if (::RegOpenKeyEx(HKEY_CURRENT_USER, _T(""), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
::RegDeleteKey(hKey, _T("\\SOFTWARE\\MySoftwareInstall"));
::RegCloseKey(hKey);
}
}
BOOL OpenFlagKey() {
BOOL bOpened = FALSE;

HKEY hKey = NULL;
if (::RegOpenKeyEx(HKEY_CURRENT_USER, _T("\\SOFTWARE\\MySoftwareInstall"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
bOpened = TRUE;
::RegCloseKey(hKey);
}

return bOpened;
}
BOOL IsRemovingDuringUpdate() {
return OpenFlagKey();
}
BOOL IsInstallingDuringUpdate() {
return (OpenFlagKey() == FALSE);
}


///////////////////////////////////////////////////////////
// Setup.dll interface methods and enums.

typedef enum {
codeINSTALL_INIT_CONTINUE = 0,
codeINSTALL_INIT_CANCEL
}
codeINSTALL_INIT;

typedef enum {
codeINSTALL_EXIT_DONE = 0,
codeINSTALL_EXIT_UNINSTALL
}
codeINSTALL_EXIT;

typedef enum {
codeUNINSTALL_INIT_CONTINUE = 0,
codeUNINSTALL_INIT_CANCEL
}
codeUNINSTALL_INIT;
typedef enum {
codeUNINSTALL_EXIT_DONE = 0
}
codeUNINSTALL_EXIT;

extern "C" __declspec(dllexport) codeINSTALL_INIT Install_Init(HWND hwndParent, BOOL fFirstCall, BOOL fPreviouslyInstalled, LPCTSTR pszInstallDir) {
if (fFirstCall == TRUE) {
SetInstallingStartFlag();
}

return codeINSTALL_INIT_CONTINUE;
}

extern "C" __declspec(dllexport) codeINSTALL_EXIT Install_Exit(HWND hwndParent, LPCTSTR pszInstallDir, WORD cFailedDirs, WORD cFailedFiles, WORD cFailedRegKeys, WORD cFailedRegVals, WORD cFailedShortcuts) {
BOOL bUpdating = IsInstallingDuringUpdate();
RemoveInstallingStartFlag();

if (bUpdating == TRUE) {
// Run updating code here...
}
else {
// Run installation code here...
}

return codeINSTALL_INIT_CONTINUE;
}

extern "C" __declspec(dllexport) codeUNINSTALL_INIT Uninstall_Init(HWND hwndParent, LPCTSTR pszInstallDir) {
BOOL bUpdating = IsRemovingDuringUpdate();
RemoveInstallingStartFlag();
if (bUpdating == FALSE) {
// Run uninstallation code here...
}

return codeUNINSTALL_INIT_CONTINUE;
}

extern "C" __declspec(dllexport) codeUNINSTALL_EXIT Uninstall_Exit(HWND hwndParent) {
return codeUNINSTALL_EXIT_DONE;
}

Tuesday, October 20, 2009

Linkpool: TortoiseSVN and Password to SVN

TortoiseSVN does not allow save password to SVN. This forces entering it many times during the day. Fortunately there is a workaround and Ditching the Password Prompts in TortoiseSVN explains how.

Thursday, October 15, 2009

What is MaxBuild Property in .inf File for Cabwiz is Actually For

When installing cab file on devices that have square screens or support screen rotation (last is applicable to all devices starting from WM 2003 SE) you may receive an error message:
The program you have installed may not dispay properly because it was designed for a previous version of Windows Mobile software.
Text of this message is not really correct because actually cab installer complains about screen on WM, not OS version.
To omit this error MaxBuild property declared in Vestion section of .inf file can be used. According to Microsoft:
The BuildMax value can be used to indicate that the application supports square screens (BuildMax=0xA0000000), screen rotation (BuildMax=0xC0000000), or both (BuildMax=0xE0000000).
This is one of those odd things that we can found in sometimes. Error message leads us to wrong direction and name of property doesn't have any connection to what it does :)

Wednesday, October 14, 2009

Hard Reset HTC S730

Yesterday HTC S730 that I use for development hang and after soft reset I couldn't start it again.
So I had to perform hard reset using special key combination: holding both soft buttons press power button. At first it didn't work. After spending couple of minutes on Internet I found that there is a trick: power button must be pressed only for a second and then released.
After very first try I successfully reset the phone :)

Tuesday, October 6, 2009

Linkpool: UI design

Today I watched a video of Ryan Singer from 37sygnals that I want to share about:
  • UI Fundamentals for Programmers: great presentation about UI fundamentals that covers such aspects of UI design as thinking about model, actions and differentiation of information instead of sets of fields and forms.
  • This video reminded me another Ryan's presentation at FOWD. I would recommend watch the first one and then first 5 min from FOWD video plus last 15 min (starting at 34th min).

Friday, October 2, 2009

Hiding Applications to Tray

Last week I found great utility called TrayIt! that allows to hide applications to tray when instead of minimizing to taskbar.
It has very simple interface and works stable. I use it to hide Outlook Express and Lotus Notes.

P.S.
There is also utitlity specially for OutlookExpress (HideOI).