Hiding curl Window on Windows - ruby

One of the answers on a previous question mentioned that I can use curl to fetch a url; this can be done in Thread.new or in Process.spawn. But it seems that in either case, on Windows, I get a small command-prompt window appearing while curl is going out to the network.
I am invoking curl like this:
`curl "#{url}"`
Is there any way to hide the window so that it doesn't appear? Not only does it grab the focus away from the game (freezing it), but if I make frequent calls, it will be extremely annoying to the end user.

After some experimenting i got it working, no window when doubleclicking on the script, i use WMI from ruby, you just have to alter the path to curl.
IMPORTANT: save it with the extension .rbw and make sure that rubyw.exe is associated with that extenstion.
#hidden_curl.rbw
require 'win32ole'
HIDDEN_WINDOW = 0
cmd = '"C:\\Program Files\\curl\\curl.exe" --output c:\\test2.txt "http://stackoverflow.com/questions/10869789/hiding-curl-window-on-windows"'
objStartup = WIN32OLE.connect("winmgmts:\\\\.\\root\\cimv2:Win32_ProcessStartup")
objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
objProcess = WIN32OLE.connect("winmgmts:root\\cimv2:Win32_Process")
errReturn = objProcess.Create(cmd, nil, objConfig, nil)
Hope this works on your system.

You could try passing the -s option to curl which will make it run in silent mode.
Something like
`curl -s "#{url}"`
I am guessing this will not show up the console.

I think you problem is that you run the command in a subshell and the subshell in windows is CMD which is attached to a window.
I don't have a ruby to test the following but you could try :
IO#popen
Runs the specified command string as a subprocess;
The subprocess‘s standard input and output will be connected to the returned IO object.
=> http://ruby-doc.org/core-1.8.6/IO.html if IO is available to you
you could also try to run
start /B curl -s "#{url}" instead of just curl see http://www.computerhope.com/starthlp.htm for start specs.

This solution doesn't pop up a window on my W7 system
cmd = '"C:\Program Files\curl\curl.exe" --silent --output c:\test.txt "http://stackoverflow.com/questions/10869789/hiding-curl-window-on-windows"'
IO.popen(cmd)
or without creating a file
cmd = '"C:\Program Files\curl\curl.exe" --silent "http://stackoverflow.com/questions/10869789/hiding-curl-window-on-windows"'
IO.popen(cmd, "w+") { |io| puts io.readlines }

Related

How to programatically call executable in ruby

I'm trying to dynamically call a program depending if a user has it installed or not
#program_path = %x(which x)
unless $?.success?
#download program to a location
#set path to above location
#program_path = "$HOME/Downloads/location"
end
`#{#program_path} login -r #{HOST} -n #{NICKNAME} -u #{#username} -P #{#password}`
It runs properly when the program is not installed.
But when it is installed it seems to not call the full program I have in backticks - like its missing the arguments?
Similarly it doesn't work with %x either.
What am I missing?
chomp!
#program_path = %x(which x).chomp

how to suppress/remove ALL output from a cURL command (ruby)

I have:
info = `curl -s http://www.{insertwebsitehere}.com`
followed by some more arguments and I want to suppress everything that gets printed to the terminal. i know that -s got rid of the progress bar but I can't figure out how to completely remove ALL output of the cURL command.
This command gets run many times during the execution of the program and the output it produces messes everything up.
From what I understand there is no argument which removes it all and i have to redirect it, i just can't figure out how.
I've tried adding > /dev/null/ to the end of it but it gave me errors
any ideas?
thanks
You can suppress stderr by adding 2>/dev/null:
info = `curl -s http://www.{insertwebsitehere}.com 2>/dev/null`
but better way is to use some http library and fetch your page without starting additional process in a shell. For example there's curb - libcurl bindings for ruby
Remove / from the end of /dev/null
info = `curl -s http://www.{insertwebsitehere}.com > /dev/null`
But this will set info to empty string.
I think it is not what you want.

Execute basic windows commands

I would like to achieve this using win32ole only and not any other way to execute shell commands in ruby.
require 'win32ole'
shell = WIN32OLE.new('Shell.Application')
my_username = shell.ShellExecute('cmd.exe', 'username', '', 'open', 0)
puts my_username
#Current output => nil
Just want to print my username but generally would like to execute any commands and get its output. I know we have ENV['user'] or echo %username% gives me what I want but want this using win32ole only.
Thanks a lot in advance.
You should try with whoami instead of username:
require 'win32ole'
shell = WIN32OLE.new('Shell.Application')
my_username = shell.ShellExecute('cmd.exe', 'whoami', '', 'open', 0)
puts my_username
You can't use ShellExecute() because it doesn't let you access the output of the command your run which is what you want. See Using ShellExecuteEx and capturing standard in/out/err for more informations about that point.
I would simply use puts ENV['USERNAME'] which works like a charm. (Or any command given by Ilia Aptsiauri in his answer)
If you just want to execute Windows CLI commands you need to take little bit different approach.
Instead of whoami you can put any command you want
system("whoami")
`whoami` (these are backticks)
spawn("whoami")
The difference between those are the following
system waits until "The command" has finished and outputs everything
to $stdout. Then it returns true or false depending on the exitstatus.
The backticks wait as well, but return the output made by the program.
spawn doesn't wait, but rather returns the PID of the subprocess. Note
that this requires Ruby 1.9 on Windows to work.
There is one more option check Open3 library it get's little bit more information during the output.

Command executes when typed, but not when generated?

I made a powershell script to generate a ruby command. The command takes forever to execute
when generated and run by the script. However, when its typed, it runs quickly and gets
the job done. Script logic is :
$dat1 = one ruby command | Out-String
# $dat1 will contain the value - rake drive:unit_tests:load_data
$dat2 = " parameters here"
$dat3 = $dat1 + $dat2
$dat3 = $ExecutionContext.InvokeCommand.NewScriptBlock($dat3)
& $dat3
Can someone please help me to figure out why this is happening and how to resolve this ?
Solution: Execute your script using the following command:
powershell -noexit "&" "c:\myscripts\script1.ps1"
I just got lucky here. Since I am new to powershell, I don't know why this
works. I read one link, but I still don't understand why it works.
http://poshoholic.com/2007/09/27/invoking-a-powershell-script-from-cmdexe-or-start-run/

vbs how to get result from a command line command

I want to get the result of a simple command from the command line (cmd.exe) using a Windows script (.vbs). How is this done? I haven't been able to find a good/simple example or explanation. You could use the "date" or "time" command to provide an example with.
Such as:
P.S. I am able to write the script code that opens cmd.exe and sends the command.
Thanks!
When in doubt, read the documentation. You probably want something like this:
Set p = CreateObject("WScript.Shell").Exec("%COMSPEC% /c date /t")
Do While p.Status = 0
WScript.Sleep 100
Loop
WScript.Echo p.StdOut.ReadAll
Edit: When using Exec() you pass input via the .StdIn descriptor, not via SendKeys() (which is a rather unreliable way of passing input anyway).
%COMSPEC% is a system environment variable with the full path to cmd.exe and the /c option makes cmd.exe exit after the command (date /t in the example) is finished.
If the command indicates success/failure with an exit code, you can check the ExitCode property after the command finished.
If p.Status <> 0 Then WScript.Echo p.ExitCode
Edit2: Instead of using atprogram interactively, can you construct commandlines that will perform particular tasks without user interaction? With non-interactive commandlines something like this might work:
prompt = "C:\>"
atprogram_cmdline_1 = "atprogram.exe ..."
atprogram_cmdline_2 = "atprogram.exe ..."
'...
Function ReadOutput(p)
text = ""
Do Until Right(text, Len(prompt)) = prompt
text = text & p.StdOut.Read(1)
Loop
ReadOutput = text
End Function
Set cmd = CreateObject("WScript.Shell").Exec("%COMSPEC% /k")
ReadOutput cmd ' skip over first prompt
cmd.StdIn.WriteLine(atprogram_cmdline_1)
WScript.Echo ReadOutput(cmd)
cmd.StdIn.WriteLine(atprogram_cmdline_2)
WScript.Echo ReadOutput(cmd)
'...
cmd.Terminate ' exit CMD.EXE
%COMSPEC% /k spawns a command prompt without running a command. The /k prevents it from closing. Because it isn't closing automatically, you can't use the While p.Status = 0 loop here. If a command needs some time to finish, you need to WScript.Sleep a number of seconds.
Via cmd.StdIn.WriteLine you can run commandlines in the CMD instance. The function ReadOutput() reads the output from StdOut until the next prompt appears. You need to look for the prompt, because read operations are blocking, so you can't simply say "read all that's been printed yet".
After you're finished you quit CMD.EXE via cmd.Terminate.

Resources