inno setup exec sqlcmd command problems with files path with spaces - inno-setup

i am trying to execute 2 scripts using inno setup.
The problem i think is the path of the file that contains spaces.
The scripts are working because i already tried the hardcoded path with no spaces and it does work.
there is this post where this problem is discribed and a solution is added but i have tried and it doesnt work.
this is the topic Inno Setup, spaces and double quote in [Run]
in order not to use hardcoded paths i am using inno setup constants, so on the output folder i have a setup.exe and and folder called testfolder with the 2 scripts, one is for creating a database, and the other is to create the tables.
in inno setup did this
connExe:=ExpandConstant('{tmp}')+'\sqlcmd.exe';
pathFx1:=ExpandConstant('{src}')+'\testfolder\teste.sql';
pathFx2:=ExpandConstant('{src}')+'\testfolder\idontimedb.des';
Exec(connExe,' -S DEV3\IDONICSYS4 -U sa -P idsysadmin -i \""'+connFx1+'\""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
MsgBox(IntToStr(ResultCode), mbError, mb_Ok);
Exec(connExe,' -S DEV3\IDONICSYS4 -d MSSQLTIPS -U sa -P idsysadmin -i \""'+connFx2+'\""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
MsgBox(IntToStr(ResultCode), mbError, mb_Ok);
when i run both messages boxs show code 2,but i am still unable to find what does this code means.
I think my problem is with the backslash and the quotation marks position , but i have already tried different combination and it doesnt work..
Thanks for the help.
the full path of the files are:
C:\Users\hsilva\Documents\Inno setupo scripts\Setup\Output\testfolder\teste.sql \create database
C:\Users\hsilva\Documents\Inno setupo scripts\Setup\Output\testfolder\idontimedb.des \create tables
C:\Users\hsilva\Documents\Inno setupo scripts\Setup\Output\setup.exe \executable
thanks in advance...
UPDATE - 27/10/2014
so as user LTama sugested(thanks once again TLama) i have checked the files that were needed for running the scripts.. and the files needed were commented,i made a few changes and now it is giving me code 1.What does it mean?
i use the code found in this site http://0x3f.org/blog/howto-execute-sql-scripts-in-inno-setup/ and made a few changes.
in the files section i have got this:
Source: "C:\Users\hsilva\Documents\InnoSetup\sqlcmd.exe"; Flags: dontcopy ;
Source: "C:\Users\hsilva\Documents\InnoSetup\sqlcmd.rll"; Flags: dontcopy ;
Do i need to have these 2 files, because when installing sql server 2008 r2, these files are installed , and available?
in the code section i have got this:
procedure DeinitializeSetup();
var
connExe:String;
connFx1:String;
begin
ExtractTemporaryFile('sqlcmd.exe');
ExtractTemporaryFile('sqlcmd.rll');
connExe:=ExpandConstant('{tmp}')+'\sqlcmd.exe';
connFx1:=ExpandConstant('{src}')+'\folder\teste.sql';
Exec(connExe,' -S DEV3\IDONICSYS4 -U sa -P idsysadmin -i \""'+connFx1+'\""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
MsgBox(IntToStr(ResultCode), mbError, mb_Ok);
end;
end;
this is execute in the end of setup, i ommited some of the checks like checking if the instance exists..

here what i think..
1. Does the command work outside of Inno Setup Script?
Use LOG(); to test the string pass to exe in a command window.
Extract the teste.sql to {tmp}
Source: "C:\Users\hsilva\Documents\InnoSetup\teste.sql"; Flags: dontcopy ;
function CustomForm_NextButtonClick(Page: TWizardPage): Boolean;
var
connExe:String;
connFx1:String;
connTxt:String;
ResultCode: Integer;
begin
// need to sql server in dropdown list
// sqlcmd -L > text.txt
ExtractTemporaryFile('sqlcmd.rll');
ExtractTemporaryFile('sqlcmd.exe');
connExe:=ExpandConstant('{tmp}')+'\sqlcmd.exe';
connTxt := ' -S ' + lstSqlServer.text + ' -U '+ txtUsername.Text + ' -P ' + txtPassword.Text + ' -Q "CREATE DATABASE ' + txtDatabase.Text + '"' + ' -o ' +
// use log to view and test the string in a command window
Log('The Value is connTxt: ' + connTxt );
if Exec(connExe, connTxt, '' , SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
//MsgBox(IntToStr(ResultCode), mbError, mb_Ok);
ExtractTemporaryFile('onestep2012.sql');
connFx1:=ExpandConstant('{tmp}\OneStep2012.sql');
connTxt := ' -S ' + lstSqlServer.text + ' -U '+ txtUsername.Text + ' -P ' + txtPassword.Text + ' -d ' + txtDatabase.Text + ' -i ' + connFx1 + ' -o ' + ExpandConstant('{tmp}\log.log');
Log('The Value is connTxt: ' + connTxt );
if Exec(connExe, connTxt, '' , SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
MsgBox( 'The '+ txtDatabase.Text + ' OneStep Database is ready for use' , mbInformation, mb_Ok);
result := True;
end;
end;
end;

Related

Automate obtaining the SHA256 for a file to download with Inno Setup 6.1?

The documentation for DownloadTemporaryFile says this about the RequiredSHA256OfFile parameter:
If RequiredSHA256OfFile is set it will compare this to the SHA-256 of the downloaded file and raise an exception if the hashes don't match.
An exception will be raised if there was an error. Otherwise, returns the number of bytes downloaded. Returns 0 if RequiredSHA256OfFile is set and the file was already downloaded.
From the answer here I have determined that the correct commandline method to obtain the checksum is:
CertUtil -hashfile MSAHelpDocumentationSetup.exe SHA256
This is how I add adding this particular file to my script:
AddFileForDownload('{#HelpDocSetupURL}', 'HelpDocSetup.exe');
Which expands to:
procedure AddFileForDownload(Url, FileName: string);
begin
DownloadPage.Add(Url, FileName, '');
FilesToDownload := FilesToDownload + ' ' + ExtractFileName(FileName) + #13#10;
Log('File to download: ' + Url);
end;
Is there way to automate:
Obtaining the checksum for my file.
Caching that checksum into a string.
Using that checksum value when building the script.
By automating this task it will provide two benefits:
Minimize user error in copy /pasting the checksum value.
Keep the checksum update to date without user interaction.
Is this feasible in Inno Setup with Pascal Script?
Pascal Script won't help you. You need the value at the compile time. So using a preprocessor. You can indeed execute the certutil. But imo, in this case, it's easier to use PowerShell and its Get-FileHash cmdlet:
#define GetSHA256OfFile(FileName) \
Local[0] = AddBackslash(GetEnv("TEMP")) + "sha256.txt", \
Local[1] = \
"-ExecutionPolicy Unrestricted -Command """ + \
"Set-Content -Path '" + Local[0] + "' -NoNewline -Value " + \
"(Get-FileHash('" + FileName + "')).Hash" + \
"""", \
Exec("powershell.exe", Local[1], SourcePath, , SW_HIDE), \
Local[2] = FileOpen(Local[0]), \
Local[3] = FileRead(Local[2]), \
FileClose(Local[2]), \
DeleteFileNow(Local[0]), \
LowerCase(Local[3])
And then you can use it like:
AddFileForDownload(
'{#HelpDocSetupURL}', 'HelpDocSetup.exe', '{#GetSHA256OfFile("HelpDocSetup.exe")}');
You of course need to add the third parameter to your AddFileForDownload function and pass it to TDownloadWizardPage.Add. You also may need to add a path to the file, so that the preprocessor can find it.

Run Sql server script to update dataBase with cmd in Inno setup

I am working to update sql server data base with a setup that made by Inno setup.
I write this line of command in cmd
sqlcmd -s myserverName -U sa -P MyPass -d myDataBase -i scriptAddress
and it work correctly and i want to do same In Inno setup and Write this lines of code
procedure UpdateDataBase;
var
Param:String;
Kode : integer;
FileName :String;
begin
InstanceName:= DEF_INSTANCENAME;
InstancePass:= DEF_DBPASSWORD;
DataBaseName:= DEF_DATABASENAME;
serverName:= 'SINA-PC\RMPRO';
FileName:= 'C:\Update2008to2018.sql';
Param:= ' sqlcmd -S '+ServerName+' -U sa -P '+ InstancePass+ ' -d '+ DataBaseName+ ' -i '+
FileName;
if Exec('cmd.exe',param ,'', SW_SHOW, ewWaitUntilTerminated,kode) then
begin
showMessage('Tamam');
end;
end;
but after call this procedure i have an empty cmd window. what should I do
You probably should be calling sqlcmd.exe directly rather than as a parameter to cmd.exe. So, you should have something like (haven't tested but should get you started):
pgm := 'sqlcmd.exe';
Param := '-S '+ServerName+' -U sa -P '+ InstancePass+ ' -d '+ DataBaseName+ ' -i '+ FileName;
if Exec(pgm, param, '', SW_SHOW, ewWaitUntilTerminated, kode) then
begin
MsgBox('Done.', mbInformation, MB_OK);
end;

How to replace directory with its constant in a ShellExec line [duplicate]

This question already has an answer here:
Inno Setup Constant in Code Section
(1 answer)
Closed 4 years ago.
I have this working line:
ShellExec('',ExpandConstant('{app}\iush.exe'),'/ui "C:\Program Files (x86)\Myapp"', ' ', SW_HIDE, ewWaitUntilTerminated, errorCode)
But i want to replace the Program Files (x86) dirctory with its constant: "C:\Program Files (x86)\Myapp" >> {pf32}\Myapp
Then It would like:
ShellExec('',ExpandConstant('{app}\iush.exe'),'/ui "{pf32}\Myapp"', ' ', SW_HIDE, ewWaitUntilTerminated, errorCode)
ShellExec('',ExpandConstant('{app}\iush.exe'),ExpandConstant('/ui "{pf32}\Myapp"'),'',SW_HIDE,ewWaitUntilTerminated,errorCode);

How to check if port is usable in Inno Setup?

I need to check some port is usable or not? How can do that in Inno Setup?
Is there any way to use socket in to Inno Setup? Is there any library for this? If there how can import it and use it?
Thank you for your answers.
You can use my function to check, if a port is available:
function CheckPortOccupied(Port:String):Boolean;
var
ResultCode: Integer;
begin
Exec(ExpandConstant('{cmd}'), '/C netstat -na | findstr'+' /C:":'+Port+' "', '', 0,
ewWaitUntilTerminated, ResultCode);
if ResultCode <> 1 then
begin
Log('this port('+Port+') is occupied');
Result := True;
end
else
begin
Result := False;
end;
end;
Function to return (in MsgBox) service or program that use port 80.
MsgBox will not shown if output is empty.
function NextButtonClick(CurPage: Integer): Boolean;
var
TmpFileName, ExecStdout: string;
ResultCode: integer;
begin
if CurPage = wpWelcome then
begin
TmpFileName := ExpandConstant('{tmp}') + '\~pid.txt';
Exec('cmd.exe',
'/C FOR /F "usebackq tokens=5 delims= " %i IN (`netstat -ano ^|find "0.0:80"`) DO '
+ '#tasklist /fi "pid eq %i" | find "%i" > "' + TmpFileName + '"', '', SW_HIDE,
ewWaitUntilTerminated, ResultCode);
if LoadStringFromFile(TmpFileName, ExecStdout) then
begin
MsgBox('Port 80 is used by '#13 + ExecStdout, mbInformation, MB_OK);
end;
DeleteFile(TmpFileName);
end;
Result := True;
end;

Error while passing bash user input to sql statement

I am trying to write a bash function which prompts for the schema owner and drops all the corresponding schemas.
function db_cleanup
{
#accept user input
read -p "Schema Owner: " input
sqlplus -s $usr1/$pwd1#$sid1 << EOF
declare
usr_d varchar2(10) := '&input'; --reas user input here
sqlstmt varchar2(128);
begin
sqlstmt := 'drop user '||$usr_d||' cascade';
dbms_output.put_line(sqlstmt); execute immediate sqlstmt;
sqlstmt := 'drop user ab_'||$usr_d||' cascade';
dbms_output.put_line(sqlstmt); execute immediate sqlstmt;
sqlstmt := 'drop user xy_'||$usr_d||' cascade';
dbms_output.put_line(sqlstmt); execute immediate sqlstmt;
end;
/
EOF
}
Output looks like:
Enter Schema Owner: ABC
Enter value for usr_in:
User requested Interrupt or EOF detected.
-bash-3.2$
Please let me know how to fix this one. Thanks in advance.
Pulling together comments from #244an and myself:
'&input' should be '$input', because you're referring to a shell variable.
$usr_d should be usr_d (without the $) because you are not referring to a sheel variable here; this is coming from the PL/SQL declare section.
the -s flag to SQL*Plus suppresses the banners; but you original question showed that so not sure if you've lost that somewhere along the way.
So:
function db_cleanup
{
#accept user input
read -p "Schema Owner: " input
sqlplus -s $usr1/$pwd1#$sid1 << EOF
set timing off
set feedback off
set serverputput on size 10000
spool $log_file.out
declare
usr_d varchar2(10) := '$input';
sqlstmt varchar2(128);
begin
sqlstmt := 'drop user '||usr_d||' cascade';
dbms_output.put_line(sqlstmt);
execute immediate sqlstmt;
sqlstmt := 'drop user ab_'||usr_d||' cascade';
dbms_output.put_line(sqlstmt);
execute immediate sqlstmt;
sqlstmt := 'drop user xy_'||usr_d||' cascade';
dbms_output.put_line(sqlstmt);
execute immediate sqlstmt;
end;
/
EOF
}
Not sure if you might want to sanitize the schema you're given... there are a number of users you really don't want to drop by accident. Any of these for a start, and you might have your own too.

Resources