0

我正在使用 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

我究竟做错了什么?

4

3 回答 3

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
于 2013-06-25T12:34:05.513 回答
2

让我补充一下,nsis有一个json 插件

于 2013-06-25T13:14:17.297 回答
1

你做错的是你直接使用文本框的句柄,所以它不会显示实际的文本而是句柄的ID。为了让它工作,编辑你poolPageLeavefunction如下:

 Function poolPageLeave
${NSD_GetText} $POOL $POOL
${NSD_GetText} $USER $USER
${NSD_GetText} $PASS $PASS
FunctionEnd
于 2013-06-25T12:41:15.757 回答