开发者

Batch file can't immediately see environment variables created by InstallShield script

开发者 https://www.devze.com 2022-12-17 19:36 出处:网络
We use InstallShield 2008 for our product installation. Product开发者_运维技巧 consists of several components. When a component is installed, a batch-file with some post-install routines specific to t

We use InstallShield 2008 for our product installation. Product开发者_运维技巧 consists of several components. When a component is installed, a batch-file with some post-install routines specific to this component is executed.

The problem: post-install batch files use some environment variables that are set during the installation of the product through InstallScript. But it seems that batch-files can't see immediate changes in registry (and newly created environment variables).

Is there a way to accomplish installation without a system reboot?

Potentially useful information: target system - Windows XP, currently logged in user is in Administrators group.


I had the same problem with an earlier version of InstallShield. Here's the way I solved it (quick and dirty code).

#define HWND_BROADCAST          0xffff
#define WM_SETTINGCHANGE        0x001A
function UpdateEnvironmentVariable(szKey, szValue)
  NUMBER nResult;
  STRING szEnv;
  POINTER pEnv;
begin
  nResult = RegDBSetKeyValueEx(szKey, "PATH", REGDB_STRING, szValue, -1);

  szEnv = "Environment";                    
  pEnv = &szEnv;                  
  SendMessage (HWND_BROADCAST, WM_SETTINGCHANGE, 0, pEnv );
end;

The key is to use SendMessage. Hope it helps.


InstallShield users using InstallShield 2010 or later.

Important: The InstallScript Engine has changed since Version 2010 for Unicode.

So using POINTER pEnv; will no longer work. You must use WPOINTER pEnv; instead. I personally use InstallShield 2013 and everything I found suggested the "POINTER approach", but this a piece of legacy code that does not translate to later versions.

I use the following InstallScript function in InstallShield 2013:

// Flush the NT registry to all applications.
function RefreshEnvironment()
    STRING szEnv;
    WPOINTER pEnv;
begin     
    szEnv = "Environment";
    pEnv = &szEnv;
    SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, pEnv);
end;

And for my defines I use:

// defines
#define WM_SETTINGCHANGE 0x001A
#define HWND_BROADCAST 0xffff

So the key here is broadcast WM_SETTINGCHANGE to all top-level windows. This way they are aware that a system-wide change has been made.

0

精彩评论

暂无评论...
验证码 换一张
取 消