环境变量 – Inno Setup中[Run]程序无法识别[不可用]环境变量

前端之家收集整理的这篇文章主要介绍了环境变量 – Inno Setup中[Run]程序无法识别[不可用]环境变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个license.exe文件,我最后在我的设置代码调用,

在正常工作之前,代码需要设置环境变量,

代码如下:

[Registry]
; set PATH
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueType: string; ValueName: "PATH"; ValueData: "{app}"

[Setup]
; Tell Windows Explorer to reload the environment
ChangesEnvironment=yes

[Run]
Filename: "{app}\temp\installation_files\license.exe";

这里代码执行,但找不到正确的路径.

当我检查系统环境变量时,它设置正确,

当我手动运行license.exe代码后,它可以正常工作并查看环境变量.

有人能告诉我如何解决这个问题吗?

或者如何延迟[Run]部分直到系统识别出环境变量?

解决方法

为[Run]部分执行条目而创建的进程继承了其父进程的环境块,即安装程序本身.因此,您必须将环境变量设置为安装程序,并将其继承到已执行的应用程序.如何做到这一点如下面的脚本所示:
[Run]
Filename: "{app}\temp\installation_files\license.exe"; BeforeInstall: SetEnvPath

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif
function SetEnvironmentVariable(lpName: string; lpValue: string): BOOL;
  external 'SetEnvironmentVariable{#AW}@kernel32.dll stdcall';

procedure SetEnvPath;
begin
  if not SetEnvironmentVariable('PATH',ExpandConstant('{app}')) then
    MsgBox(SysErrorMessage(DLLGetLastError),mbError,MB_OK);
end;

以前的答案通知系统的其他部分变量变化:

正如@Jerry在他的评论中指出的那样,在处理[Run]部分后会执行有关环境变化的通知.实际上,安装程序执行了one of the last things.

因此,要在处理[Run]部分之前通知系统有关环境更改,您需要有一个解决方法.我重写了从Inno安装代码到脚本的RefreshEnvironment程序.如果将ChangesEnvironment指令设置为yes,则它与执行的功能相同.

在以下脚本中,我删除了ChangesEnvironment指令,并从注册表项的AfterInstall参数函数添加了RefreshEnvironment过程的执行:

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
    ValueType: string; ValueName: "PATH"; ValueData: "{app}"; \
    AfterInstall: RefreshEnvironment;

[Run]
Filename: "{app}\temp\installation_files\license.exe";

[Code]
const
  SMTO_ABORTIFHUNG = 2;
  WM_WININICHANGE = $001A;
  WM_SETTINGCHANGE = WM_WININICHANGE;

type
  WPARAM = UINT_PTR;
  LPARAM = INT_PTR;
  LRESULT = INT_PTR;

function SendTextMessageTimeout(hWnd: HWND; Msg: UINT;
  wParam: WPARAM; lParam: PAnsiChar; fuFlags: UINT;
  uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
  external 'SendMessageTimeoutA@user32.dll stdcall';  

procedure RefreshEnvironment;
var
  S: AnsiString;
  MsgResult: DWORD;
begin
  S := 'Environment';
  SendTextMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,PAnsiChar(S),SMTO_ABORTIFHUNG,5000,MsgResult);
end;

猜你在找的Delphi相关文章