NSIS Compile - mysql Not Recognised as operable pr

2020-01-19 04:47发布

问题:

I have stared at this until almost BLIND! Checked PATH Environment, Use DOS shortname where possible etc. Below is script with test results and comments. I have search many posts prior to submission of following.

---- TESTS 01 - 04 follow ; Var $SYSDIR = c:\Windows\System32

; =======================================================================

[TEST-01]
Var folder
StrCpy $folder "$PROGRAMFILES64\MySQL\MySQL Server 5.7"

[TEST-STMT-01]
nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "$folder\bin\mysql.exe" -u$login -p -e "SHOW DATABASES;"' $0

[TEST-ERR-01]
'c:\PROGRAM' is not recognized as an internal or external command, operable program or batch file.

; Returns an error code $0 = 1 (error, space after PROGRAM in "c:\PROGRAM FILES\MySQL...)"

; =======================================================================
[TEST-02]
Var folder
StrCpy $folder "c:\PROGRA~1\MySQL\MySQL Server 5.7"

[TEST-STMT-02]
nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "$folder\bin\mysql.exe" -u$login -p -e "SHOW DATABASES;"' $0

[TEST-ERR-02]
'c:\PROGRA~1\MySQL\MySQL' is not recognized as an internal or external command, operable program or batch file.

; Returns an error code $0 = 1 (error, space after MySQL in "...\MySQL\MySQL Server 5.7)"

; =======================================================================

[TEST-03] Var folder
StrCpy $folder "c:\PROGRAM FILES\MySQL\MySQL Server 5.7"

[TEST-STMT-03]
nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "$folder\bin\mysql.exe" -u$login -p -e "SHOW DATABASES;"' $0

[TEST-ERR-03]
'c:\PROGRAM' is not recognized as an internal or external command, operable program or batch file.

; Returns an error code $0 = 1 (error, space after PROGRAM in "c:\PROGRAM FILES\MySQL...)"

; =======================================================================

[TEST-04] Var folder
StrCpy $folder "NOT USED"

[TEST-STMT-04]
nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "c:\PROGRAM FILES\MySQL\MySQL Server 5.7\bin\mysql.exe" -u$login -p -e "SHOW DATABASES;"' $0

[TEST-ERR-04]
'c:\PROGRAM' is not recognized as an internal or external command, operable program or batch file.

; Returns an error code $0 = 1 (error, space after PROGRAM in "c:\PROGRAM FILES\MySQL...)"

; ========================================================================= Any Suggestions would be appreciated!

Name "MySQL script Installation"

# use variables initialized from custom.ini
Var folder
Var login
Var errorsrc

!define DBNAME demo      ; target database

# Included files
!include MUI2.nsh
!include LogicLib.nsh

OutFile Sample_script.exe

ShowInstDetails show

Page custom GetInfos "" ": Information page"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

# Ensure the user has Administrator Rights
Function .onInit

###NOTE: Only one STRCPY valid for TEST-01 thru TEST-04
;; StrCpy $folder "$PROGRAMFILES64\MySQL\MySQL Server 5.7"   # TEST-01
StrCpy $folder "c:\PROGRA~1\MySQL\MySQL Server 5.7"       # TEST-02
;; StrCpy $folder "c:\PROGRAM FILES\MySQL\MySQL Server 5.7"  # TEST-03
;; StrCpy $folder "NOT USED"                                 # TEST-04
StrCpy $login root

FunctionEnd

Section -Main

DetailPrint "verify SysDir: $SYSDIR"
DetailPrint "verify nsEXEC target: $folder\bin\mysql.exe"

###NOTE TEST-01 thru TEST-03 USE 1st nsEXEC stmt, COMMENT ";;" 2nd nsEXEC stmt
nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "$folder\bin\mysql.exe" -u$login -p -e "SHOW DATABASES;"'    # TEST01 - 03
### TEST-04 comment ";;" previous nsEXEC  and un-comment " " next nsExec statement                   # TEST-04
;;    nsExec::ExecToLog '"$SYSDIR\cmd.exe" /c "c:\PROGRAM FILES\MySQL\MySQL Server 5.7\bin\mysql.exe"  -u$login -p -e "SHOW DATABASES;"'
Pop $0  # Get Results

StrCmp "error" $0 +1 +2
DetailPrint "return-error: $0"    ; ck return = 'error'
DetailPrint "return-err:   $0"    ; return = 1

StrCmp $0 1 +1 +3
StrCpy $errorsrc "DB Connect Error - Wrong login or password"
Goto abortinst

##    DetailPrint "Check Options Switch"
##    Check Switch Create DB = 1 true, then CREATE database before, else IMPORT
##    StrCmp $createdb 1 createdbs importdbs

createdbs:
DetailPrint "Creating DATABASE"
##  Do it .....
Goto abortinst

importdbs:
DetailPrint "IMPORT SQL files"
##   do it......
Goto endinst

abortinst:
DetailPrint "                         "
DetailPrint "$\n An error occured ! $\n"
DetailPrint "  $errorsrc              "
DetailPrint "                         "
Abort

endinst:
DetailPrint "ADD Table Successful     "
SectionEnd

Function GetInfos
!insertmacro MUI_HEADER_TEXT "Database informations" "Database informations - please fill all elements"
;;    !insertmacro INSTALLOPTIONS_DISPLAY "custom.ini"
FunctionEnd

回答1:

'c:\PROGRAM' is not recognized as an internal or external command, operable program or batch file.

This is telling you that there's a problem with the path leading up to your MySQL folder. You should know it's a problem because there's spaces within it's path.

!define SQLFLD `$PROGRAMFILES64\MySQL\MySQL Server 5.7`

ReadEnvStr $R0 COMSPEC
ExecDos::Exec /TOSTACK `"$R0" /c "${SQLFLD}\bin\mysql.exe"  -u$login -p -e "SHOW DATABASES;"`

Try this.. haven't tested this myself though.



回答2:

Working Solution - 3 commponents NSIS script, custom.ini and batch CMD file [NSIS Script] Name "MySQL Database IMPORT"

Var mysql_dir
Var mysql_root
var srcepath
var srcescript
Var login
Var password
Var dbname
Var createdb
Var cmdpath
Var errorsrc

# Included files
!include MUI2.nsh
!include LogicLib.nsh
!include InstallOptions.nsh
!include X64.nsh

OutFile AddSQLtbl-4.exe
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
CRCCheck on
XPStyle on

ShowInstDetails show

BrandingText "MYSQL import - XXXXXXX"

Page custom GetInfos "" ": Information page"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

####--------------------------------------------
!macro VerifyUserIsAdmin
UserInfo::GetAccountType
pop $0
${If} $0 != "admin" ;Require admin rights on NT4+
    messageBox mb_iconstop "Error - Administrator rights required!"
    setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
    quit
${EndIf}
!macroend

# Ensure the user has Administrator Rights
Function .onInit
setShellVarContext all
!insertmacro VerifyUserIsAdmin

InitPluginsDir
!insertmacro INSTALLOPTIONS_EXTRACT "custom.ini"
!insertmacro INSTALLOPTIONS_WRITE "custom.ini" "Field 10" "State"    "$dbname"
FunctionEnd

####--------------------------------------------
Section -Main
#      Extract data from custom.ini
ReadINIStr $dbname "$PLUGINSDIR\custom.ini" "Field 14" "State"
DetailPrint "...Install DBNAME: $dbname"         #14# dbname
ReadINIStr $mysql_dir "$PLUGINSDIR\custom.ini" "Field 2" "State"
DetailPrint "...MySQL Base: $mysql_dir"          #02# MySQL base dir
ReadINIStr $mysql_root "$PLUGINSDIR\custom.ini" "Field 4" "State"
DetailPrint "...MySQL Root: $mysql_root"         #04# MySQL Data
ReadINIStr $srcepath "$PLUGINSDIR\custom.ini" "Field 6" "State"
DetailPrint "...MySQL Script Path: $srcepath"    #06# MySQL input script path
ReadINIStr $srcescript "$PLUGINSDIR\custom.ini" "Field 8" "State"
DetailPrint "...MySQL Script File: $srcescript"  #08# MySQL input script
ReadINIStr $login "$PLUGINSDIR\custom.ini" "Field 10" "State"
DetailPrint "...Login User: $login"              #10# user
ReadINIStr $password "$PLUGINSDIR\custom.ini" "Field 12" "State"
#      donot print Password
ReadINIStr $createdb "$PLUGINSDIR\custom.ini" "Field 15" "State"
StrCmp $createdb 1 +1 +2
DetailPrint "...MySQL CREATE Database: $createdb"  #15# #9 = 1 true
DetailPrint "...MySQL IMPORT Database: $createdb"  #15# #9 = 0 false
ReadINIStr $cmdpath "$PLUGINSDIR\custom.ini" "Field 17" "State"
DetailPrint "...IMPORT Batch CMD: $cmdpath"       #17# Batch Cmd Path

####--------[CONNECT]------------------------------------
#      Check if Login Works
ClearErrors
ExecWait 'mysql.exe -u$login -p$password -e "SHOW DATABASES;"' $0
Pop $0  # Get Results

StrCmp "error" $0 +1 +3
DetailPrint "CONNECT return-error: $0"
goto seterr-conn

StrCmp "0" $0 +1 +3
DetailPrint "CONNECT return-OK: $0"
goto ckcreate

StrCmp $0 1 +1 +3
StrCpy $errorsrc "Wrong login or password"
Goto seterr-conn

####-----------[CREATE]---------------------------------
#    Check Switch Create DB = 1 true, then CREATE database, else IMPORT
ckcreate:
DetailPrint "Check Options Switch [$createdb]"

StrCmp $createdb 1 createdbs importdbs

createdbs:
DetailPrint "CREATE DATABASE - $dbname"

ClearErrors
ExecWait 'mysql -u$login -p$password -e "CREATE DATABASE $dbname"' $1
Pop $1  # Get Results

StrCmp "error" $1 +1 +2
DetailPrint "CREATE return-error: $1"
DetailPrint "CREATE return-OK: $1"

StrCmp $1 1 +1 +3
StrCpy $errorsrc "Unable to CREATE database"
Goto seterr-cre

####------------[IMPORT]--------------------------------
#   IMPORT Database
importdbs:
DetailPrint "IMPORT SQL files to db=$dbname User=$login Pswd=********"
StrCpy $0 '"$cmdpath" $dbname $srcescript "$srcepath" $login'
ClearErrors
ExecWait  "$0"  $3

Pop $3  # Get Results
StrCmp "error" $3 +1 +3
DetailPrint "IMPORT return-error: $3"
goto seterr-imp

StrCmp "0" $3 +1 seterr-imp
DetailPrint "IMPORT return-OK: $3"
goto endinst
seterr-conn:
StrCpy $errorsrc "   Login CONNECTION Err - ck user | password"
goto prterr
seterr-cre:
StrCpy $errorsrc "   CREATE DB Err - dbname specified?"
goto prterr
seterr-imp:
StrCpy $errorsrc "   File IMPORT Err - ck source"
prterr:
DetailPrint "                         "
DetailPrint "$\n An error occured ! $\n"
DetailPrint "  $errorsrc              "
DetailPrint "                         "
Goto endsection

endinst:
DetailPrint "ADD Table Successful     "
endsection:
SectionEnd

Function GetInfos
!insertmacro MUI_HEADER_TEXT "Database informations" "Database informations - please fill all elements"
!insertmacro INSTALLOPTIONS_DISPLAY "custom.ini"
FunctionEnd

[**Custom.ini**]
[Settings]
NumFields=17
CancelEnabled=1
Title=XXXXXX - MySQL Database Installation
CancelShow=1
BackEnabled=1

[Field 1]
Type=Label
Text=MySQL Base Dir
Left=2
Right=45
Top=0
Bottom=8

[Field 2]
Type=DirRequest
Left=84
Top=0
Right=294
Bottom=12
Flags=PATH_MUST_EXIST
State="c:\PROGRA~1\MySQL\MySQL Server 5.7"
MinLen=3

[Field 3]
Type=Label
Text=MySQL ROOT Dir
Left=2
Right=80
Top=16
Bottom=24

[Field 4]
Type=DirRequest
MinLen=24
Flags=PATH_MUST_EXIST
State="c:\%PROGRAMDATA%\MySQL\MySQL Server 5.7\Data"
Left=84
Right=294
Top=16
Bottom=28

[Field 5]
Type=Label
Left=2
Top=32
Right=80
Bottom=40
Text=MySQL Script Dir

[Field 6]
Type=DirRequest
Left=84
Top=32
Right=294
Bottom=44
MinLen=3
Flags=PATH_MUST_EXIST
State=c:\_temp-c\dumps

[Field 7]
Type=Label
Left=2
Top=52
Right=86
Bottom=60
Text=MySQL Script Name

[Field 8]
Type=FileRequest
Left=83
Top=52
Right=215
Bottom=64
MinLen=3
Flags=FILE_MUST_EXIST
State=demo_users.sql

[Field 9]
Type=Label
Left=2
Top=70
Right=78
Bottom=78
Text=MySQL Login

[Field 10]
Type=Text
Left=84
Top=70
Right=138
Bottom=82
State=root

[Field 11]
Type=Label
Left=142
Top=70
Right=177
Bottom=78
Text=Password

[Field 12]
Type=Password
Left=180
Top=70
Right=255
Bottom=82

[Field 13]
Type=Label
Text=MySQL Database name
Left=2
Right=78
Top=86
Bottom=94

[Field 14]
Type=Text
Left=84
Top=86
Right=172
Bottom=98
State=demo

[Field 15]
Type=CheckBox
Left=202
Top=86
Right=306
Bottom=94
Text=" CREATE database 1|0"
State=1

[Field 16]
Type=Label
Text=Batch CMD Exec
Left=2
Right=71
Top=104
Bottom=112

[Field 17]
Type=FileRequest
MinLen=3
Flags=FILE_MUST_EXIST
State=c:\_Temp-C\db-IMPORT.cmd
Left=84
Right=216
Top=104
Bottom=116

[**Batch CMD file**]
@echo off
REM  IMPORT MySQL Script to Database
REM  Single Database or Multiple databases, depends on input file.sql
REM
REM    CMD> db-IMPORT dbname [scriptFile] [scriptDir] [dbUser]
REM
REM    scriptDir:  _Temp-C\Dumps folder - [default]
REM    scriptFile: Dump-yyyymmdd-dbname - [Default]
REM             where - yyyymmdd = current date
REM
REM    Date: June 6,2017 wimbre
REM    Reference URL:  https://ss64.com/nt/if.html
REM    
title MySQL Script to Database IMPORT [Restore]
SETLOCAL
echo ''
echo %~n0: use: db-import dbname [scriptFile]
echo %~n0:           (1): %1 (2): %2 (3): %3 (4): %4
SET "dbname=%1"
set "_mydate=%date:~10,4%%date:~4,2%%date:~7,2%"
ECHO %~n0: Today: %_mydate%
SET "_scriptDir=c:\_temp-c\dumps"
SET "_scriptFile=Dump-%_mydate%-%1.sql"
REM SET "_scriptFile=Demo_users.sql"
SET "dbuser=root"
SET "errorlevel="
REM            Ck dbname NUL
IF [%~1]==[] goto :dbNul

:dbName
REM             dbname - cli parameter is Not NUL
goto :CkSrce

:dbNul
REM             dbname - cli parameter is NUL
echo ''
echo %~n0: enter: db-IMPORT dbname [scriptFile] [scriptDir] [dbuser]
echo %~n0: required dbname %1 NOT specified - Restart
GOTO :end

:CkSrce
REM             CK [_scriptFile] NULL use default name
IF [%2]==[] goto :srceFileNul

:srceFile
REM             [_scriptFile] - cli parameter is NOT NULL
SET  "_scriptFile=%2"
goto :cksrceDir

:srceFileNul
REM             [scriptFile] - cli parameter is NULL
echo ''
echo %~n0: command:   db-IMPORT %1
echo %~n0:   scriptFile defaults to: [ %_scriptFile% ]
echo %~n0:   scriptDir  defaults to: [ %_scriptDir% ]
echo %~n0:   dbuser     defaults to: [ %dbuser% ]
goto :doit

:cksrceDir 
REM             CK [_scriptDir] NULL use default name
IF [%3]==[] goto :srceDirNul

REM             [_scriptDir] - cli parameter is  NOT NULL
:srceDir
SET  "_scriptDir=%~3"   
goto :ckdbUser 

REM             [scriptDir] - cli parameter is NULL
:srceDirNul
echo ''
echo %~n0: command: db-IMPORT %1 %2 %3 %4
echo %~n0:   scriptFile entered:    [ %_scriptFile% ]
echo %~n0:   scriptDir defaults to: [ %_scriptDir% ]
echo %~n0:   dbuser (n)   defaults to: [ %dbuser% ]
goto :doit

:ckdbUser 
REM             CK [dbUser] NULL use default    
IF [%4]==[] goto :dbUserNul 

REM             [dbUser] - cli parameter is  NOT NULL   
SET  "dbuser=%~4"
REM  echo Parm4: %~4 dbUser: %dbuser%
echo %~n0: command:   db-IMPORT %1 %2 %3 %4
echo %~n0:   scriptFile entered:     [ %_scriptFile% ]
echo %~n0:   scriptDir  entered:     [ %_scriptDir% ]
echo %~n0:   dbuser     entered:     [ %dbuser% ]   
goto :doit

:dbUserNul  
echo ''
echo %~n0: command: db-IMPORT %1 %2 %3 %4
echo %~n0:   scriptFile entered:    [ %_scriptFile% ]
echo %~n0:   scriptDir entered:     [ %_scriptDir% ]
echo %~n0:   dbuser    defaults to: [ %dbuser% ]

:doit
REM             IMPORT file.sql
echo %~n0:   scriptDir\File:  [ %_scriptDir%\%_scriptFile% ]
echo %~n0:   user=[ %dbuser% ]

mysql  -u%dbuser% -p %1 < "%_scriptDir%\%_scriptFile%"
IF %ERRORLEVEL%==1 (
    echo "error=%ERRORLEVEL%"
    echo %~n0: Database [ %1 ] Not Present, Must use 'db-CREATE %1'
    echo %~n0: Return=%ERRORLEVEL%
    goto :end
)

echo %~n0: Return=%ERRORLEVEL%
:end
exit /b %errorlevel%
ENDLOCAL
pause
cls