I want to use WinSCP command line in my application. I want to inline all commands and not have script file.
Is it possible to hide server name?
I don't want the users know the server name.
I need to have command window visible in order to see the progress of download file.
Call Shell("c:\program files (x86)\winscp\winscp.com /ini=nul /command ""open ftp://user:password#servername/ "" ""get -latest /public_ftp/incoming/* c:\local\"" ""exit""", vbNormalFocus)
What you want is doable, but it involves a lot of advanced code for redirecting an output of winscp.com, and filtering out the information you do not want to show.
Easier is to use WinSCP .NET assembly from PowerShell instead. That gives you a full control over the output.
Just execute something like this:
PowerShell -ExecutionPolicy bypass -Command "$sessionUrl = 'ftp://user:password#servername/' ; $remotePath = '/public_ftp/incoming' ; $localPath = 'c:\local' ; try { Add-Type -Path 'C:\Program Files (x86)\WinSCP\WinSCPnet.dll' ; $sessionOptions = New-Object WinSCP.SessionOptions ; $sessionOptions.ParseUrl($sessionUrl) ; echo 'Opening connection'; $session = New-Object WinSCP.Session ; $session.add_FileTransferProgress( { Write-Host -NoNewline ([char]13 + '{0} ({1:P0})' -f $_.FileName, $_.FileProgress) } ); $session.Open($sessionOptions) ; echo 'Finding latest file'; $directoryInfo = $session.ListDirectory($remotePath) ; $latest = $directoryInfo.Files | Where-Object { -Not $_.IsDirectory } | Sort-Object LastWriteTime -Descending | Select-Object -First 1 ; if ($latest -eq $Null) { Write-Host 'No file found' ; exit; }; echo 'Downloading file'; $session.GetFiles([WinSCP.RemotePath]::EscapeFileMask([WinSCP.RemotePath]::Combine($remotePath, $latest.Name)), $localPath + '\*').Check(); echo ' Done'; } catch { Write-Host $_.Exception.Message; }"
The PowerShell code is basically equivalent to WinSCP article on Downloading the most recent file.
It's just merged into a single command, so that you can execute it from VBA Shell function (after properly doubling the double quotes).
Call Shell ( _
"PowerShell -ExecutionPolicy bypass -Command """ & _
"$sessionUrl = 'ftp://user:password#servername/';" & _
"$remotePath = '/public_ftp/incoming';" & _
"$localPath = 'c:\local';" & _
"try {" & _
" Add-Type -Path 'C:\Program Files (x86)\WinSCP\WinSCPnet.dll'; " & _
" $sessionOptions = New-Object WinSCP.SessionOptions; " & _
" $sessionOptions.ParseUrl($sessionUrl); " & _
" echo 'Opening connection'; " & _
" $session = New-Object WinSCP.Session; " & _
" $session.add_FileTransferProgress( { Write-Host -NoNewline ([char]13 + '{0} ({1:P0})' -f $_.FileName, $_.FileProgress) } ); " & _
" $session.Open($sessionOptions); " & _
" echo 'Finding latest file'; " & _
" $directoryInfo = $session.ListDirectory($remotePath); " & _
" $latest = $directoryInfo.Files | Where-Object { -Not $_.IsDirectory } | " & _
" Sort-Object LastWriteTime -Descending | Select-Object -First 1; " & _
" if ($latest -eq $Null) { Write-Host 'No file found' ; exit; }; " & _
" echo 'Downloading file'; " & _
" $sourcePath = [WinSCP.RemotePath]::EscapeFileMask([WinSCP.RemotePath]::Combine($remotePath, $latest.Name)); " & _
" $session.GetFiles($sourcePath, $localPath + '\*').Check(); " & _
" echo ' Done'; " & _
"} catch { Write-Host $_.Exception.Message; }")
Related
I have this code, and I´m calling one Java program to pass the aurguments, that I select in VB.
My issues is:
The cmd windows open, but I can't see what the program is doing, I only see on the window the arguments that are pass, and when finish, the window don't close.
enter image description here
and when program stop, the windows don't close.
enter image description here
This is the result if I run by command line
enter image description here
txbSendCommand.Text = "java -jar FACTEMICLI-2.5.16-33194-cmdClient.jar " & "-i " & TextBox1.Text & "" & " -n " & stNIF & " -p " & stPassword & " -a " & iAno & " -m " & iMes & " -op " & stvalidar & stFicheiroEscolhido & " -o c:\saft\outputfile.xml"
Dim stcaminhoexterno As String
If stErrorMessage = False Then
Dim app As New ProcessStartInfo("cmd.exe") With {.RedirectStandardInput = True, .UseShellExecute = False, .CreateNoWindow = False}
Dim myProcess As New Process
myProcess = Process.Start(app)
Dim arguments As String = txbSendCommand.Text
myProcess.StandardInput.WriteLine(arguments)
myProcess.Close()
End If
How can I see the results in the external windows, or better even in a windows or something that I can have in the form.
How Can the window close after the process is done
I have the following statement I'd like to execute in Powershell(x86) using VBA:
%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy -Scope CurrentUser Unrestricted -force;
$DBPath = "U:\Data\Distribution\Common\Dist\Weekly Hours Entry\DC Master Production DB V2\Packing Slip Generation\PackingSlipGeneratorBE.accdb";
$SQL = "SELECT VENDOR, PackingSlipID, EntryNumber, ShipDate, TrackingNumber, RA, EntryDate FROM tblPackingSlipLog WHERE EntryNumber>1000001 AND EntryNumber<1000011;";
$Output = "C:\Users\foo\Documents\Test.csv";
$Con= New-Object -TypeName System.Data.OleDb.OleDbConnection;
$con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= $DBpath";
$ConCommand= $Con.CreateCommand();$ConCommand.CommandText = $SQL;
$OAdapt = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $ConCommand;
$DS = New-Object -TypeName System.Data.DataSet;$OAdapt.Fill($DS);
export-csv -InputObject $DS.Tables[0] -Path $Output -NoTypeInformation -force;$Con.Close()
I am able to run just the Powershell(x86) in Powershell(x86) with no problem. Also, if I run the %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe part in command prompt and then the powershell part separately, it also works as intended. However, when I try running them together it doesn't work.
The calling VBA function: GetPackingSlipData ("WHERE EntryNumber>1000001 AND EntryNumber<1000011")
Function GetPackingSlipData(strSQL_WhereClause As String) As String
On Error Resume Next
Dim wsShell As Object
Dim strPowerShellCommand As String
Dim strOutputFile As String
strOutputFile = GetDocuments & "\Test.csv"
Set wsShell = CreateObject("WScript.Shell")
strPowerShellCommand = "%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy -Scope CurrentUser Unrestricted -force; $DBPath = ""U:\Data\Distribution\Common\Dist\Weekly Hours Entry\DC Master Production DB V2\Packing Slip Generation\PackingSlipGeneratorBE.accdb""; " & _
"$SQL = ""SELECT VENDOR, PackingSlipID, EntryNumber, ShipDate, TrackingNumber, RA, EntryDate FROM tblPackingSlipLog " & strSQL_WhereClause & ";"";" & _
"$Output = """ & strOutputFile & """;" & _
"$Con= New-Object -TypeName System.Data.OleDb.OleDbConnection;$con.ConnectionString = ""Provider=Microsoft.ACE.OLEDB.12.0;Data Source= $DBpath"";" & _
"$ConCommand= $Con.CreateCommand();$ConCommand.CommandText = $SQL;" & _
"$OAdapt = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $ConCommand;" & _
"$DS = New-Object -TypeName System.Data.DataSet;$OAdapt.Fill($DS);" & _
"export-csv -InputObject $DS.Tables[0] -Path $Output -NoTypeInformation -force;$Con.Close()"
Debug.Print strPowerShellCommand
Call wsShell.Run(strPowerShellCommand, 1, True)
If Err.Number <> 0 Then
GetPackingSlipData = "Error: " & Err.Number & ", " & Err.Description
Else
GetPackingSlipData = strOutputFile
End If
On Error GoTo 0
End Function
The command that gets printed:
%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy -Scope CurrentUser Unrestricted -force; $DBPath = "U:\Data\Distribution\Common\Dist\Weekly Hours Entry\DC Master Production DB V2\Packing Slip Generation\PackingSlipGeneratorBE.accdb"; $SQL = "SELECT VENDOR, PackingSlipID, EntryNumber, ShipDate, TrackingNumber, RA, EntryDate FROM tblPackingSlipLog WHERE EntryNumber>1000001 AND EntryNumber<1000011;";$Output = "C:\Users\foo\Documents\Test.csv";$Con= New-Object -TypeName System.Data.OleDb.OleDbConnection;$con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= $DBpath";$ConCommand= $Con.CreateCommand();$ConCommand.CommandText = $SQL;$OAdapt = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $ConCommand;$DS = New-Object -TypeName System.Data.DataSet;$OAdapt.Fill($DS);export-csv -InputObject $DS.Tables[0] -Path $Output -NoTypeInformation -force;$Con.Close()
I'm using AppleScript and shell to curl files from my local system to an AWS S3 bucket. I'm able to accomplish this calling a bash script from AppleScript, but when I try to use strictly AppleScript I get a "SignatureDoesNotMatch" error from AWS.
Anybody see what might be wrong?
There is an existing thread on this where the OP encountered the same problem then finally gave up on this method and used PHP.
AppleScript do shell script cURL command for Amazon s3
My code:
--File info
set filePath to "/Volumes/MyFolder"
set fileName to "001.jpg"
--AWS Info
set awsRegion to "s3-us-west-1"
set bucketName to "mybucketname"
set awsPath to "mysubfolder"
set s3key to "myawskey"
set s3secret to "myawssecretkey"
--Build cannonical request
set acl to "x-amz-acl:public-read"
set contentType to "application/octet-stream"
set storageType to "x-amz-storage-class:STANDARD"
--set theDate to do shell script "date '+%a, %d %b %Y %T %z'"
set theDate to do shell script "date -R"
set connonicalString to "PUT\\n\\n" & contentType & "\\n" & theDate & "\\n" & acl & "\\n" & storageType & "\\n/" & bucketName & "/" & awsPath & "/" & fileName
set signatureCommand to "echo -en " & connonicalString & " | openssl sha1 -hmac " & s3secret & " -binary | base64"
set signature to do shell script signatureCommand
--Build the curl command
set curlCommand to "curl -s -X PUT"
set sourcePath to " -T " & filePath & "/" & fileName
set header01 to " -H 'Host: " & bucketName & "." & awsRegion & ".amazonaws.com'"
set header02 to " -H 'Date: " & theDate & "'"
set header03 to " -H 'Content-Type: " & contentType & "'"
set header04 to " -H '" & storageType & "'"
set header05 to " -H '" & acl & "'"
set header06 to " -H 'Authorization: AWS " & s3key & ":" & signature & "'"
set targetPath to " https://" & bucketName & "." & awsRegion & ".amazonaws.com/" & awsPath & "/" & fileName
set shellCommand to curlCommand & sourcePath & header01 & header02 & header03 & header04 & header05 & header06 & targetPath
--Run the script
do shell script shellCommand
Here is the error:
SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method....
The problem you cite is due to the shell being used by applescript: it's /bin/sh
but your terminal emulator is probably using BASH (/bin/bash).
Therein, the echo used in /bin/sh seems not to accept switches!
i.e., "-en " got rolled into what becomes applescript variable |connonicalString|
Either substitute for echo -en with printf %s (no trailing space!) or use heredoc syntax for variable signatureCommand for its use in
do shell script signatureCommand
set signatureCommand to "/bin/bash <<EOF
echo -en " & connonicalString & " | openssl sha1 -hmac " & s3secret & " -binary | base64
EOF"
Compare this output done in a terminal window running BASH:
Last login: Tue Mar 24 12:17:22 on ttys003
mylocal:~ myself$ echo -en PUT\n\napplication/octet-stream\nTue, 24 Mar 2020 16:07:09 -0400\nx-amz-acl:public-read\nx-amz-storage-class:STANDARD\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
CpUNJTkp6i1ocERz7PQ+Q/m5rYI=
With this output done in a terminal window running /bin/sh:
mylocal:~ myself$ /bin/sh
mylocal:~ myself$ echo -en PUT\n\napplication/octet-stream\nTue, 24 Mar 2020 16:07:09 -0400\nx-amz-acl:public-read\nx-amz-storage-class:STANDARD\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
Wy1tNXiDmDsdlm/sBDDYCoc0kik=
Then observe what is the output in Script Editor using its default /bin/sh:
tell current application
do shell script "date -R"
--> "Tue, 24 Mar 2020 16:07:09 -0400"
do shell script "echo -en PUT\\n\\napplication/octet-stream\\nTue, 24 Mar 2020 16:07:09 -0400\\nx-amz-acl:public-read\\nx-amz-storage-class:STANDARD\\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64"
--> "Wy1tNXiDmDsdlm/sBDDYCoc0kik="
end tell
Result:
"Wy1tNXiDmDsdlm/sBDDYCoc0kik="
and then forcing it to use /bin/bash:
tell current application
do shell script "date -R"
--> "Tue, 24 Mar 2020 16:46:47 -0400"
do shell script "/bin/bash <<EOF
echo -en PUT\\n\\napplication/octet-stream\\nTue, 24 Mar 2020 16:07:09 -0400\\nx-amz-acl:public-read\\nx-amz-storage-class:STANDARD\\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
EOF"
--> "CpUNJTkp6i1ocERz7PQ+Q/m5rYI="
end tell
Result:
"CpUNJTkp6i1ocERz7PQ+Q/m5rYI="
I was trying to use shell function in vb.net to run a program and then write/export the result else where , it works on win8 but not XP !! The command line prints this error
'C:\Documents' is not recognized as an internal or external command,
operable program or batch file.
Press any key to continue . . .
Dim save as String="C:\exported.txt"
Dim command As String = tempPath & "app.exe -f " & IO.Path.GetTempPath & " -o " & save & " & pause"
shell("cmd /c " & command, AppWinStyle.NormalFocus, True)
Process.Start(IO.Path.Combine(tempPath, "app.exe"), "-f """ & IO.Path.GetTempPath & """ -o """ & Save() & """ & pause")
You hace a folder in the command with a space in it (probably the documents and Settings folder). cmd.exe has no way of telling whether the space is in the file name or the end of the file name, unless you put the file name in "" - like "C:\doxuments and Settings..."
Dim command As String = tempPath & "app.exe -f \"" & IO.Path.GetTempPath & "\" -o \"" & save & "\" & pause"
(\" is intended to escape a " so that it translates to embedding a " in the string. I'm not sure what the VB syntax is.)
EDIT:
I think #Roy van der Velde below has the 'escaping correct. The final part not checked is tempPath. See my comment on the question.
i want my program to open cmd , change directory and then do the command : "copy /B file1 file2 output"
this is what i have at the moment. but all that happens is a cmd window flashes for a second but no file gets created
Dim cmd1 As String
Dim cmd2 As String
cmd1 = "cd " & FolderFromFileName(imagename)
cmd2 = "copy /B " & NameOnlyFromFullPath(imagename) & "+" & "TEMP.txt" & " " & TextBox1.Text
Shell("cmd /c" & " " & cmd1 & " " & cmd2, AppWinStyle.NormalFocus)
please help, thanks :)
Do you really need to have a command prompt appear? You could do all this without a separate process by using the system.io library. If you really need the cmd prompt you can create a process.
Dim NewProcess = New Process
' a new process is created
NewProcess.StartInfo.UseShellExecute = False
' redirect IO
' PVWCmd.StartInfo.RedirectStandardOutput = True
' PVWCmd.StartInfo.RedirectStandardError = True
' PVWCmd.StartInfo.RedirectStandardInput = True
' don't even bring up the console window
NewProcess.StartInfo.CreateNoWindow = False
' executable command line info
NewProcess.StartInfo.FileName = "cmd"
NewProcess.StartInfo.WorkingDirectory = "C:\"
' NewProcess.StartInfo.Arguments = +" > """ + "LogFile.log" + """ 2>&1"
NewProcess.Start()