字符串内的变量 - 在NSIS中是否可以进行字符串插值?

时间:2013-06-25 11:45:30

标签: nsis

我正在使用NSIS构建一个安装程序,以帮助我将cgminer部署到我的地下室中的一堆计算机上。安装程序要求两件事:

  • 挖掘池URL和工作人员凭据
  • 提取cgminer的目录

安装程序使用用户提供的池URL,登录名和密码生成简单的cgminer配置文件。

以下是编写JSON配置文件的代码:

FileOpen $9 $INSTDIR\config.conf w ;Opens a Empty File for writing
FileWrite $9 "{$\r$\n"
FileWrite $9 "$\"pools$\" : [$\r$\n"
FileWrite $9 "$\t{$\r$\n"
FileWrite $9 "$\t$\t$\"url$\" : $\"$POOL$\",$\r$\n"
FileWrite $9 "$\t$\t$\"user$\" : $\"$USER$\",$\r$\n"
FileWrite $9 "$\t$\t$\"pass$\" : $\"$PASS$\",$\r$\n"
FileWrite $9 "$\t}$\r$\n"
FileWrite $9 "],$\r$\n"
FileWrite $9 "$\r$\n"
FileWrite $9 "$\"intensity$\" : $\"d$\"$\r$\n"
FileWrite $9 "}$\r$\n"
FileClose $9 ; closes the file

这就是我所期待的:

{
"pools" : [
        {
                "url" : "http://bc.minercity.org:4583",
                "user" : "fizzlefazzle_miner",
                "pass" : "rosebud",
        }
],

"intensity" : "d"
}

然而,这就是我得到的:

{
"pools" : [
        {
                "url" : "1639776",
                "user" : "1115594",
                "pass" : "1115614",
        }
],

"intensity" : "d"
}

我假设我正在获取内存地址而不是我输入的字符串。以下是完整的代码:

; bitcoinminer.nsi
;
; sets up a basic bitcoin miner.
; asks user for mining pool and user/pass
; installs cgminer to <OS DRIVE>\Documents and Settings\<CURRENT USER>\Local Settings\Application Data\ccc\bitcoin\cgminer
; generates cgminer config file and puts it in above dir
;

;--------------------------------

; Includes

!include nsDialogs.nsh
!include LogicLib.nsh

;--------------------------------

; The name of the installer
Name "Bitcoin Miner"

OutFile BitcoinMiner.exe

; The default installation directory
InstallDir "$PROFILE\Local Settings\Application Data\ccc\bitcoin\cgminer2"

; Request application privileges for Windows Vista
RequestExecutionLevel user


;--------------------------------

; Pages

Page Custom poolPageCreate poolPageLeave
Page directory
Page instfiles

Var POOL
Var USER
Var PASS

Function poolPageCreate

    nsDialogs::Create 1018  ; creates a new dialog and returns it's HWND on the stack
    Pop $0                  ; HWID of new dialog stored to $0

    ${NSD_CreateLabel} 0 0u 75% 12u "Pool URL (ex: http://bc.minercity.org:6347)" ; create label. HWND on the stack
    Pop $0                                                                   ; HWID of new label stored to $0

    ${NSD_CreateText} 0 13u 100% 12u 'http://bc.minercity.org:6347'                
    Pop $POOL
    GetFunctionAddress $0 poolChange
    nsDialogs::OnChange $POOL $0

    ${NSD_CreateLabel} 0 40u 75% 12u "Login name (ex: fizzlefazzle_miner)"
    Pop $0  

    ${NSD_CreateText} 0 53u 100% 12u 'fizzlefazzle_miner'
    Pop $USER
    GetFunctionAddress $0 userChange
    nsDialogs::OnChange $USER $0

    ${NSD_CreateLabel} 0 77u 75% 12u "Password (ex: rosebud)"
    Pop $0

    ${NSD_CreateText} 0 90u 100% 12u 'rosebud'
    Pop $PASS
    GetFunctionAddress $0 passChange
    nsDialogs::OnChange $PASS $0

    nsDialogs::Show

FunctionEnd

Function poolPageLeave

FunctionEnd

Function poolChange

    Pop $0 # HWND
    System::Call user32::GetWindowText(i$POOL,t.r0,i${NSIS_MAX_STRLEN})

FunctionEnd


Function userChange

    Pop $0
    System::Call user32::GetWindowText(i$USER,t.r0,i${NSIS_MAX_STRLEN})

FunctionEnd

Function passChange

    Pop $0
    System::Call user32::GetWindowText(i$PASS,t.r0,i${NSIS_MAX_STRLEN})

FunctionEnd

Section

;--------------------------------

; The stuff to install

  ; Set output path to the installation directory.
  SetOutPath $INSTDIR

  ; Put file there
  File /r "cgminer\"

  FileOpen $9 $INSTDIR\config.conf w ;Opens a Empty File for writing
  FileWrite $9 "{$\r$\n"
  FileWrite $9 "$\"pools$\" : [$\r$\n"
  FileWrite $9 "$\t{$\r$\n"
  FileWrite $9 "$\t$\t$\"url$\" : $\"$POOL$\",$\r$\n"
  FileWrite $9 "$\t$\t$\"user$\" : $\"$USER$\",$\r$\n"
  FileWrite $9 "$\t$\t$\"pass$\" : $\"$PASS$\",$\r$\n"
  FileWrite $9 "$\t}$\r$\n"
  FileWrite $9 "],$\r$\n"
  FileWrite $9 "$\r$\n"
  FileWrite $9 "$\"intensity$\" : $\"d$\"$\r$\n"
  FileWrite $9 "}$\r$\n"
  FileClose $9 ; closes the file

SectionEnd

我做错了什么?

3 个答案:

答案 0 :(得分:2)

字符串插值没有问题。你的问题在于处理编辑文本:例如,当你说明时。

${NSD_CreateText} 0 13u 100% 12u 'http://bc.minercity.org:6347'                
Pop $POOL
GetFunctionAddress $0 poolChange
nsDialogs::OnChange $POOL $0

您正确创建了一个编辑文本,并保留其句柄以在定义的回调中使用。但是后来

FileWrite $9 "$\t$\t$\"url$\" : $\"$POOL$\",$\r$\n"

文件写入将控制句柄存储在文件中而不是其内容中。

回调也存在一些问题:

  • 您将编辑的不同值读入同一个$0寄存器,因此$0将包含上次修改字段的文本
  • 回调仅在更改编辑时触发,如果用户不做任何更改,则不会触发回调。

我会使用3个变量作为编辑句柄,另外3个作为值,然后读取页面中的值,留下回调。如果您只想获取最终值并且不想对值更改做出反应,也可以删除3个回调:

!include nsDialogs.nsh
!include LogicLib.nsh
Name "Bitcoin Miner"
OutFile BitcoinMiner.exe
RequestExecutionLevel user

Page Custom poolPageCreate poolPageLeave
Page directory
Page instfiles

Var POOLHDL
Var USERHDL
Var PASSHDL
Var POOL
Var USER
Var PASS

Function poolPageCreate

    nsDialogs::Create 1018  ; creates a new dialog and returns it's HWND on the stack
    Pop $0                  ; HWID of new dialog stored to $0

    ${NSD_CreateLabel} 0 0u 75% 12u "Pool URL (ex: http://bc.minercity.org:6347)" ; create label. HWND on the stack
    Pop $0                                                                   ; HWID of new label stored to $0

    ${NSD_CreateText} 0 13u 100% 12u 'http://bc.minercity.org:6347'                
    Pop $POOLHDL

    ${NSD_CreateLabel} 0 40u 75% 12u "Login name (ex: fizzlefazzle_miner)"
    Pop $0  

    ${NSD_CreateText} 0 53u 100% 12u 'fizzlefazzle_miner'
    Pop $USERHDL

    ${NSD_CreateLabel} 0 77u 75% 12u "Password (ex: rosebud)"
    Pop $0

    ${NSD_CreateText} 0 90u 100% 12u 'rosebud'
    Pop $PASSHDL

    nsDialogs::Show

FunctionEnd

Function poolPageLeave
    ${NSD_GetText} $POOLHDL $POOL
    ${NSD_GetText} $USERHDL $USER 
    ${NSD_GetText} $PASSHDL $PASS 
FunctionEnd

Section

  SetOutPath $INSTDIR

  File /r "cgminer\"

  FileOpen $9 $EXEDIR\config.conf w ;Opens a Empty File for writing
  FileWrite $9 "{$\r$\n"
  FileWrite $9 "$\"pools$\" : [$\r$\n"
  FileWrite $9 "$\t{$\r$\n"
  FileWrite $9 "$\t$\t$\"url$\" : $\"$POOL$\",$\r$\n"
  FileWrite $9 "$\t$\t$\"user$\" : $\"$USER$\",$\r$\n"
  FileWrite $9 "$\t$\t$\"pass$\" : $\"$PASS$\",$\r$\n"
  FileWrite $9 "$\t}$\r$\n"
  FileWrite $9 "],$\r$\n"
  FileWrite $9 "$\r$\n"
  FileWrite $9 "$\"intensity$\" : $\"d$\"$\r$\n"
  FileWrite $9 "}$\r$\n"
  FileClose $9 ; closes the file

SectionEnd

答案 1 :(得分:2)

我要补充说,nsis有json plugin

答案 2 :(得分:1)

你做错了是你直接使用文本框的句柄,因此它不会显示实际文本而是显示句柄的ID。要使其发挥作用,请按以下方式修改poolPageLeavefunction

 Function poolPageLeave
${NSD_GetText} $POOL $POOL
${NSD_GetText} $USER $USER
${NSD_GetText} $PASS $PASS
FunctionEnd