NSIS 使用目录中的随机文件

NSIS use random file from directory

我想要它,以便在启动期间,我可以设置一个随机声音文件在安装期间播放。

我有这段代码,所以它将所有声音文件放在一个下拉列表中,以便可以更改

Function SetUserOptionsPage
 ${Locate} "$InstDrvRE\Media\SoundFiles" "/L=F /M=*.mp3" "listsoundfiles"
  StrCpy $IVO "$IVO|Random|None"
  WriteINIStr "$PLUGINSDIR\settings.ini" "Field 6" "ListItems" "$IVO"
  WriteINIStr "$PLUGINSDIR\XYfYk7xQ.dat" "Field 6" "State" "Default"
  InstallOptions::initDialog "$PLUGINSDIR\settings.ini"
  Pop [=10=]
  InstallOptions::show
  Pop [=10=]
  Abort 
Function End

Function listsoundfiles
  ${StrStrip}  ".mp3" $R7 $R0
  ${If} $R7 == "Default.mp3"
    StrCpy $LSF "$R0"
  ${Else}
    StrCpy $LSF "$LSF|$R0"
  ${EndIf}
    Push [=10=] 
FunctionEnd


Example Drop Down:
Default
Jazz
Rock
Metal
Random
None

因此,除了硬编码 "Default" 我如何 select 列表中的随机文件并将其保存到文件状态?

目录中的文件数量可能非常多,因此它需要 select 来自所有可用文件的 运行。

看来我找到了办法。可能不是最好的,但它确实有效。如果有其他需要:

找到这段代码并将其添加到我的:

 !define Rnd "!insertmacro _Rnd"
    !macro _Rnd _RetVal_ _Min_ _Max_
       Push "${_Max_}"
       Push "${_Min_}"
       Call Rnd
       Pop ${_RetVal_}
    !macroend
    Function Rnd
       Exch [=10=]  ;; Min / return value
       Exch
       Exch   ;; Max / random value
       Push ""  ;; Max - Min range
       Push ""  ;; random value buffer

       IntOp   - [=10=] ;; calculate range
       IntOp   + 1
       System::Call '*(l) i .r4'
       System::Call 'advapi32::SystemFunction036(i r4, i 4)'  ;; RtlGenRandom
       System::Call '*(l .r1)'
       System::Free 
       ;; fit value within range
       System::Int64Op  * 
       Pop 
       System::Int64Op  / 0xFFFFFFFF
       Pop 
       IntOp [=10=]  + [=10=]  ;; index with minimum value

       Pop 
       Pop 
       Pop 
       Exch [=10=]
    FunctionEnd

然后在我的原始代码中,我为计数器添加了一个变量,然后添加了另一个函数来检查与文件列表匹配的随机数。 (这是我的完整代码)

       !include WinVer.nsh
!include LogicLib.nsh
!include x64.nsh
!include FileFunc.nsh
!include MUI2.nsh
!include WinMessages.nsh
!include InstallOptions.nsh
!include Sections.nsh
!include nsDialogs.nsh

;Request application privileges
RequestExecutionLevel Admin

Page custom SetUserOptionsPage SetUserOptionsPagenext
!insertmacro MUI_PAGE_INSTFILES

;Languages
  !insertmacro MUI_LANGUAGE "English"

Function .int
    Var /GlOBAL InstDrvRE
    Var /GlOBAL numsounds
    Var /Global randomsound
    Var /Global soundnum
    Var /Global randomsoundsel
    Var /Global IVO 
    Var /Global LSF

Push $EXEPATH
Call GetRoot
Pop [=11=]
StrCpy $InstDrvRE "[=11=]"
CreateDirectory $PLUGINSDIR
    FunctionEnd

Function GetRoot
  Exch [=11=]
  Push 
  Push 
  Push 
  Push 

  StrCpy  [=11=] 2
  StrCmp  "\" UNC
    StrCpy [=11=] 
    Goto done

UNC:
  StrCpy  3
  StrLen  [=11=]
  loop:
    IntCmp   "" "" loopend
    StrCpy  [=11=] 1 
    IntOp   + 1
    StrCmp  "\" loopend loop
  loopend:
    StrCmp  "1" +3
      StrCpy  1
      Goto loop
    IntOp   - 1
    StrCpy [=11=] [=11=] 

done:
  Pop 
  Pop 
  Pop 
  Pop 
  Exch [=11=]
FunctionEnd

Function StrStrip
Exch $R0 #string
Exch
Exch $R1 #in string
Push $R2
Push $R3
Push $R4
Push $R5
 StrLen $R5 $R0
 StrCpy $R2 -1
 IntOp $R2 $R2 + 1
 StrCpy $R3 $R1 $R5 $R2
 StrCmp $R3 "" +9
 StrCmp $R3 $R0 0 -3
  StrCpy $R3 $R1 $R2
  IntOp $R2 $R2 + $R5
  StrCpy $R4 $R1 "" $R2
  StrCpy $R1 $R3$R4
  IntOp $R2 $R2 - $R5
  IntOp $R2 $R2 - 1
  Goto -10
  StrCpy $R0 $R1
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
!macro StrStrip Str InStr OutVar
 Push '${InStr}'
 Push '${Str}'
  Call StrStrip
 Pop '${OutVar}'
!macroend
!define StrStrip '!insertmacro StrStrip'

!define Rnd "!insertmacro _Rnd"
!macro _Rnd _RetVal_ _Min_ _Max_
   Push "${_Max_}"
   Push "${_Min_}"
   Call Rnd
   Pop ${_RetVal_}
!macroend
Function Rnd
   Exch [=11=]  ;; Min / return value
   Exch
   Exch   ;; Max / random value
   Push ""  ;; Max - Min range
   Push ""  ;; random value buffer

   IntOp   - [=11=] ;; calculate range
   IntOp   + 1
   System::Call '*(l) i .r4'
   System::Call 'advapi32::SystemFunction036(i r4, i 4)'  ;; RtlGenRandom
   System::Call '*(l .r1)'
   System::Free 
   ;; fit value within range
   System::Int64Op  * 
   Pop 
   System::Int64Op  / 0xFFFFFFFF
   Pop 
   IntOp [=11=]  + [=11=]  ;; index with minimum value

   Pop 
   Pop 
   Pop 
   Exch [=11=]
FunctionEnd


Function SetUserOptionsPage
${Locate} "$InstDrvRE\Media\SoundFiles" "/L=F /M=*.mp3" "listsoundfiles"
  StrCpy $IVO "$IVO|Random|None"
  WriteINIStr ".\settings.ini" "Field 2" "ListItems" "$IVO"
  InstallOptions::initDialog ".\settings.ini"
  Pop [=11=]
  InstallOptions::show
  Pop [=11=]
  Abort 
FunctionEnd

Function SetUserOptionsPagenext
FunctionEnd


Function listsoundfiles
IntOp $numsounds $numsounds + 1
  ${StrStrip}  ".mp3" $R7 $R0
  ${If} $numsounds == 1
    StrCpy $IVO "$R0"
  ${Else}
    StrCpy $IVO "$IVO|$R0"
  ${EndIf}
  Push [=11=] 
FunctionEnd

Function randomsound
IntOp $soundnum $soundnum + 1
${if} $randomsound == $soundnum
    StrCpy $randomsoundsel "$R7"
${EndIf}
  Push [=11=] 
FunctionEnd

Section
 ${Rnd} $randomsound 1 $numsounds
   StrCpy $soundnum 0
 ${Locate} "$InstDrvRE\Media\SoundFiles" "/L=F /M=*.mp3" "randomsound"
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "File Selected=$randomsoundsel,$numsounds"

SectionEnd

ini 文件

[Settings]
NumFields=2
State=0


[Field 1]
Type=Label
Left=75
Right=145
Top=21
Bottom=30
Text="Intro"
txtAlign=Center


[Field 2]
Type=DROPLIST
ListItems=Random|None
State="Sound_Screen_Click"
Flags=
Left=75
Right=145
Top=30
Bottom=40