How to play audio file on windows from command line? - windows

In Windows, is there a simple way (i.e. something you could type on a single command line) to just play a couple of .mp3 files and then exit on its own?
wmplayer, for example, does not seem to exit when finished, forcing the harried user to hunt it down and click it closed every time. (wmplayer 11 also seems to strangely repeat some files if you pass it a list.)
(The older (1990's) versions of 'mplayer' used to support a '/close' command line option, but it doesn't seem to work in wmplayer 11.)
I'd prefer to use something that everyone will have on their machine (like wmplayer, quicktime...)

Old question, new answer - you could use PowerShell:
powershell -c (New-Object Media.SoundPlayer 'c:\PathTo\YourSound.wav').PlaySync();

I have used cmdmp3. Very lightweight at 28Kb.

Use VBScript:
Set objArgs = Wscript.Arguments
if (objArgs.Count = 0) then
Wscript.echo "I need a sound file as argument!"
WScript.Quit 123
end if
Wscript.echo "Playing: " & objArgs(0) & "..."
Set objPlayer = createobject("Wmplayer.OCX.7")
With objPlayer ' saves typing
.settings.autoStart = True
.settings.volume = 50 ' 0 - 100
.settings.balance = 0 ' -100 to 100
.settings.enableErrorDialogs = False
.enableContextMenu = False
.URL = objArgs(0)
WScript.Sleep(10000) ' time to load and start playing
'.Controls.Pause() ' stop
End With
MsgBox "if WMP is still playing, clicking OK will end it", _
vbInformation, "WMP Demo finished"
If the VBScript process ends, the Media Player ends too, you have to wait for it (I don't need it, my sounds are only some seconds long).
I used this for my special case today:
https://groups.google.com/forum/#!topic/microsoft.public.scripting.vbscript/gfOOvnN8t-U

There are pure command line players. Some are listed here.
Also, WinAmp used to have command line controller called CLAMP. I am not sure if it's still alive or available but Google for it - it was pretty good.
Also, VLC has some command line capabilities though I never checked them out.

This is what I did to do it:
rem Replace the following path with your music file
start C:\Users\Username\Desktop\your-music.mp3
rem Replace 10 with how many seconds you want the player to run
ping localhost -n 10 >nul
taskkill /im wmplayer.exe
Note this requires .mp3 to be associated with wmplayer.exe (Windows Media Player).

You can use fmedia to play audio files from Windows terminal:
fmedia file1.mp3 file2.mp3
This command will start the playback of file.mp3, then file2.mp3, and then quit after the files have finished playing.
If you wish to do it in background, add --background switch to your command:
fmedia file.ogg --background
This command will start a new process in background and detach from your console immediately.
fmedia is a portable application (works without installation) and consumes very small amount of system resources. Also, its startup time is instantaneous.
P.S. Use command fmedia.exe --install to add it to your %PATH% environment variable, otherwise you need to execute it with full path, e.g. D:\fmedia\fmedia.exe

You can probably write a small VBScript which will use the Windows Media Player ActiveX control to play an audio file. You should be able to terminate the process from that too, once playing finished.
I'm looking around a bit and maybe can come up with a working solution. Might take a while, though.

I am using this improve version of Mayra Delgado's answer:
Set objArgs = Wscript.Arguments
if (objArgs.Count = 0) then
Wscript.echo "I need a sound file as argument!"
WScript.Quit 123
end if
Wscript.echo "Playing: " & objArgs(0) & "..."
Set objPlayer = createobject("Wmplayer.OCX.7")
With objPlayer ' saves typing
.settings.autoStart = True
.settings.volume = 50 ' 0 - 100
.settings.balance = 0 ' -100 to 100
.settings.enableErrorDialogs = False
.enableContextMenu = False
.URL = objArgs(0)
' Wait until play finish
While .Playstate <> 1
Wscript.Sleep 100
Wend
End With
MsgBox "if WMP is still playing, clicking OK will end it", _
vbInformation, "WMP Demo finished"

I've found that the fastest way to play .mp3 files in Windows commandline is mpeg123
I know it's not available on people's machine per default, but from my point of view, Microsoft's own players are not consistently available over different versions either.
I'm using it on a project where the execution time is essential, and features like only playing certain frames makes is very useful. I find this (in my configuration) faster than the cmdmp3 and vbscript examples mentioned in this thread.
My syntax to only play certain frames of an .mp3 file :
mpg123.exe -k 2 -n 3 -q -1 -4 beep.mp3

Here are few scripts.
mediarunner.bat - it uses windows media player active x objects so you cannot used if there's no installed Windows Media Player (though it usually comes packed with the Windows).Accepts only one argument - the path to the file you want to play.
spplayer.bat - uses SP Voice objects but can play only .wav files.Again it accepts as only argument the path to the file you want to play.
soundplayer.bat - uses Internet Explorer objects and specific bgsound tag that can be used only in internet explorer.Can play .mp3,wav,.. files. It can accepts two arguments. The file you want to play and the sound volume (a number between -10000 to 0) :
call soundplayer.bat "C:\Windows\Media\Windows Navigation Start.wav" 0

If you need something cross-platform, mplayer works well on linux and windows and is compatible with npm's play-sound.

Related

How to store the contents of the clipboard into a variable? [duplicate]

This question already has answers here:
Use clipboard from VBScript
(15 answers)
How to copy/cut a file (not the contents) to the clipboard in Windows on the command line?
(6 answers)
Closed 3 years ago.
Editor's note:
While this question is specifically about copying a file reference to the clipboard, its generic title led to answers about how to copy / get text.
As an Emacs user on Windows who often attaches files in mails, I have been looking for a utility to copy a file (not its contents) to the clipboard, just as windows explorer does on righclick/copy).
I just found this right here on SO which uses System.Windows.Forms.Clipboard` in a small program to do exactly that. But it is in C#, for which I don't have immediate access to a compiler. So I am wondering if this can be done and how.
I saw several references such as this that the clipboard is not accessible in VBScripting, but msdn shows documentation for VB so I am risking the question.
I have never written a VBScript before but I did try a few things before asking, starting with running a copy pasted a "Hello world" and then various combinations of CreateObject etc.
Update: I need to call Clipboard.SetFileDropList, so I do not think I can use ClipboardData as suggested by the answers, it does not have this method.
Update for visitors
The solution I ended up using was to compile the C# itself, I did not know I already had a compiler.
Another update for visitors
https://stackoverflow.com/a/29963268/18573 is what I am now using, quite happily.
You can do it with an html object to retrieve the contents of the clipboard:
' Get clipboard text
Set objHTML = CreateObject("htmlfile")
text = objHTML.ParentWindow.ClipboardData.GetData("text")
EDIT: I use this snippet to put text back on the clipboard, but it needs third party software; a standalone executable 'clip.exe' which can be found on Windows 2003 Server or just on the internet:
' Do something with the text
text = replace(text, "you ", "you and your dog ")
' Put it back to the clipboard
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("clip")
Set oIn = oExec.stdIn
oIn.WriteLine text
oIn.Close
(Yes, it is all a little bit hackerdyhack)
VBScript doesn't support the clipboard. Most hosts that host vbscript, such as Internet Explorer give access through the host. Therefore vbscript running in IE or an HTA can use IE's clipboard support. The scripting hosts do not give clipboard support. You can use a vbs file to start IE through COM automation, navigate to a local page (to bypass security warnings), then use IE's clipboard.
Here's a code snippit (Outp. is a text stream)
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 0
ie.Navigate2 "C:\Users\David Candy\Desktop\Filter.html"
Do
wscript.sleep 100
Loop until ie.document.readystate = "complete"
txt=ie.document.parentwindow.clipboardData.GetData("TEXT")
ie.quit
If IsNull(txt) = true then
outp.writeline "No text on clipboard"
else
outp.writeline txt
End If
You need this function (is a little modification of this):
'TO CLEAR
ClipBoard("")
'TO SET
ClipBoard("Hello World!")
'TO GET
Result = ClipBoard(Null)
Function ClipBoard(input)
'#description: A quick way to set and get your clipboard.
'#author: Jeremy England (SimplyCoded)
If IsNull(input) Then
ClipBoard = CreateObject("HTMLFile").parentWindow.clipboardData.getData("Text")
If IsNull(ClipBoard) Then ClipBoard = ""
Else
CreateObject("WScript.Shell").Run _
"mshta.exe javascript:eval(""document.parentWindow.clipboardData.setData('text','" _
& Replace(Replace(Replace(input, "'", "\\u0027"), """","\\u0022"),Chr(13),"\\r\\n") & "');window.close()"")", _
0,True
End If
End Function
For the equivalent of a "paste" operation I would run a command-line utility like ClipOut or paste, redirect output to a file and read the file contents.
return = WshShell.Run("cmd /c clipout.exe > output.txt", 0, true)
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("output.txt", 1)
text = file.ReadAll
file.Close
You can get ClipOut here: http://jasonfaulkner.com/ClipOut.aspx
You can get paste here: https://www.c3scripts.com/tutorials/msdos/paste.html
For the equivalent of a "copy" operation I would use the clip command line utility that actually comes with Windows and similar code as above.
About the clip utility: https://blogs.msdn.microsoft.com/oldnewthing/20091110-00/?p=16093

How can I use Clipboard in vbscript? [duplicate]

This question already has answers here:
Use clipboard from VBScript
(15 answers)
How to copy/cut a file (not the contents) to the clipboard in Windows on the command line?
(6 answers)
Closed 3 years ago.
Editor's note:
While this question is specifically about copying a file reference to the clipboard, its generic title led to answers about how to copy / get text.
As an Emacs user on Windows who often attaches files in mails, I have been looking for a utility to copy a file (not its contents) to the clipboard, just as windows explorer does on righclick/copy).
I just found this right here on SO which uses System.Windows.Forms.Clipboard` in a small program to do exactly that. But it is in C#, for which I don't have immediate access to a compiler. So I am wondering if this can be done and how.
I saw several references such as this that the clipboard is not accessible in VBScripting, but msdn shows documentation for VB so I am risking the question.
I have never written a VBScript before but I did try a few things before asking, starting with running a copy pasted a "Hello world" and then various combinations of CreateObject etc.
Update: I need to call Clipboard.SetFileDropList, so I do not think I can use ClipboardData as suggested by the answers, it does not have this method.
Update for visitors
The solution I ended up using was to compile the C# itself, I did not know I already had a compiler.
Another update for visitors
https://stackoverflow.com/a/29963268/18573 is what I am now using, quite happily.
You can do it with an html object to retrieve the contents of the clipboard:
' Get clipboard text
Set objHTML = CreateObject("htmlfile")
text = objHTML.ParentWindow.ClipboardData.GetData("text")
EDIT: I use this snippet to put text back on the clipboard, but it needs third party software; a standalone executable 'clip.exe' which can be found on Windows 2003 Server or just on the internet:
' Do something with the text
text = replace(text, "you ", "you and your dog ")
' Put it back to the clipboard
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("clip")
Set oIn = oExec.stdIn
oIn.WriteLine text
oIn.Close
(Yes, it is all a little bit hackerdyhack)
VBScript doesn't support the clipboard. Most hosts that host vbscript, such as Internet Explorer give access through the host. Therefore vbscript running in IE or an HTA can use IE's clipboard support. The scripting hosts do not give clipboard support. You can use a vbs file to start IE through COM automation, navigate to a local page (to bypass security warnings), then use IE's clipboard.
Here's a code snippit (Outp. is a text stream)
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 0
ie.Navigate2 "C:\Users\David Candy\Desktop\Filter.html"
Do
wscript.sleep 100
Loop until ie.document.readystate = "complete"
txt=ie.document.parentwindow.clipboardData.GetData("TEXT")
ie.quit
If IsNull(txt) = true then
outp.writeline "No text on clipboard"
else
outp.writeline txt
End If
You need this function (is a little modification of this):
'TO CLEAR
ClipBoard("")
'TO SET
ClipBoard("Hello World!")
'TO GET
Result = ClipBoard(Null)
Function ClipBoard(input)
'#description: A quick way to set and get your clipboard.
'#author: Jeremy England (SimplyCoded)
If IsNull(input) Then
ClipBoard = CreateObject("HTMLFile").parentWindow.clipboardData.getData("Text")
If IsNull(ClipBoard) Then ClipBoard = ""
Else
CreateObject("WScript.Shell").Run _
"mshta.exe javascript:eval(""document.parentWindow.clipboardData.setData('text','" _
& Replace(Replace(Replace(input, "'", "\\u0027"), """","\\u0022"),Chr(13),"\\r\\n") & "');window.close()"")", _
0,True
End If
End Function
For the equivalent of a "paste" operation I would run a command-line utility like ClipOut or paste, redirect output to a file and read the file contents.
return = WshShell.Run("cmd /c clipout.exe > output.txt", 0, true)
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("output.txt", 1)
text = file.ReadAll
file.Close
You can get ClipOut here: http://jasonfaulkner.com/ClipOut.aspx
You can get paste here: https://www.c3scripts.com/tutorials/msdos/paste.html
For the equivalent of a "copy" operation I would use the clip command line utility that actually comes with Windows and similar code as above.
About the clip utility: https://blogs.msdn.microsoft.com/oldnewthing/20091110-00/?p=16093

loop thru contents of a file in batch under windows 7

Okay, I am sure I am not the only one who asked this question before but with my limited understanding of batch file command syntax, I am at a loss. Clicking on the suggested answers before penning this question, did not get me to where I want.
Here is my situation at hand:
Everyday, I am given a bunch of URLs to launch and check for if a certain string is displaying on each of these pages in a certain period of time (some very poorly written web app creates the content of these pages) The number of URLs I am given, varies wildly from day to the next. The only constant is the file name the URLs come in.
So, I need to loop through the URLs in this file slowly such as :
(this is the Linux/Bash representation of what I want to do)
for URL in `cat URLlistFILE.txt`
do
/usr/bin/chrome $URL
sleep 30
touch semaphore file
# an AHK script checks for the existence of semaphore file on the windows side
# when it is present, it does a screen scraping and search for the string
# then remotely deletes the semaphore file and reports the findings.
sleep 30
done
so, under batch process I will have some sort of a foreach loop and launch my command as such:
C:\Users\MyUSER\AppData\Local\Google\Chrome\Application\chrome.exe %URL%
but how will I construct the for loop and assign each line to variable named URL under batch mode
And yes I can do the whole thing in Linux and not nned any batch file but this will be handed out to a lower level support who has no understanding of running any Linux desktop, likes of GNOME, KDE or others. So it has to be a batch file and run on a win7 platform.
Thanks in advance
Don't use batch for this. Languages like PowerShell or VBScript are far better suited for this kind of task.
PowerShell:
$urllist = "C:\path\to\urllist.txt"
$teststring = "..."
Get-Content $urllist | % {
$content = (Invoke-WebRequest $_).RawContent
if ( $content -match $teststring ) {
Write-Host "$_`tOK" -ForegroundColor green
} else {
Write-Host "$_`tNOK" -ForegroundColor red
}
}
VBScript:
Set fso = CreateObject("Scripting.FileSystemObject")
urllist = "C:\path\to\urllist.txt"
teststring = "..."
For Each url In Split(fso.OpenTextFile(urllist).ReadAll, vbNewLine)
Set req = CreateObject("Msxml2.XMLHttp.6.0")
req.open "GET", url, False
req.send
If req.status = 200 Then
If InStr(req.responseText, teststring) Then
WScript.Echo url & vbTab & "OK"
Else
WScript.Echo url & vbTab & "Not OK"
End If
End If
Next

Capture CMD output with AutoHotkey

I'm trying to read Windows CMD's stdout with AutoHotkey. For example, I'd like to have the output of the setconsole command inside AHK stored in a variable. I already achieved it a while ago, which makes me all the more perplex why it's not working now.
In the AHK forums, there's a rather old thread about CMDret, a DLL based functionality to do exactly what I want. The first problem was to find a working download for it, since all the links in the post were dead. Google gave me another site, hosting v3.1.2. Altough there seems to be a newer one (v3.2.1 respectively 4d Beta), I checked it out and tested a simple example:
msgbox % CMDret(COMSPEC " /C set")
CMDret(CMD)
{
VarSetCapacity(StrOut, 10000)
RetVal := DllCall("cmdret.dll\RunReturn", "str", CMD, "str", StrOut)
Return, %StrOut%
}
Unfortunately, the MsgBox contained nothing. I then checked out RetVal which had a value of 0; and the attached readme says:
If the function fails, the return value is zero.
Further down, it says:
Note: only 32 bit console applications will currently work with the
this dll version of CMDret (v3.1.2 or lower). Calls that require
command.com will likely not produce any output and may crash. To avoid
this I have included a file named "cmdstub.exe" with the download (in
the Win9x folder). This file should be used when calling 16 bit
console applications to enable returning output.
In conclusion, I am not sure what the problem is. My machine is running on 64 bit. But is the corresponding clause in the readme supposed to solely exclude 16 bit systems or does it rather only include 32 bit?
If the computing architecture is probably not the problem, then what could be?
What I am looking for is either one of the following:
Can I fix the problem and keep using v3.1.2?
Has anyone a working source (or even a local copy) of a newer version I could check out?
Is there another approach [library, .ahk code, etc.] I could use for my purpose? (preferably similar, because CMDret seems very straightforward)
If you don't need a live output, you could use the cmd box itself to save a text file of itself and then you could have autohotkey detect when the console's PID finished (using the returned result of runwait and read the outputted file into memory.
So you could do this in your run command (just a regular cmd parameter):
ipconfig > myoutput.txt
exit
Now you have a text file with the ipconfig output in it.
OR
you could do the same thing, but instead of outputting to a text file, you could output to the clipboard, like this:
ipconfig | clip
Then, since the output is on the clipboard, you can easily grab it into autohotkey.
New recommended 2 ways of doing as of Nov 2019 - https://www.autohotkey.com/docs/FAQ.htm#output:
How can the output of a command line operation be retrieved?
Testing shows that due to file caching, a temporary file can be very fast for relatively small outputs. In fact, if the file is deleted immediately after use, it often does not actually get written to disk. For example:
RunWait %ComSpec% /c dir > C:\My Temp File.txt
FileRead, VarToContainContents, C:\My Temp File.txt
FileDelete, C:\My Temp File.txt
To avoid using a temporary file (especially if the output is large), consider using the
Shell.Exec() method as shown in the examples for the Run command.
Example for the Run command - https://www.autohotkey.com/docs/commands/Run.htm#StdOut:
MsgBox % RunWaitOne("dir " A_ScriptDir)
RunWaitOne(command) {
shell := ComObjCreate("WScript.Shell")
exec := shell.Exec(ComSpec " /C " command)
return exec.StdOut.ReadAll()
}
Note: the latter method (shell.Exec) will cause quick display of a cmd window.
You can reduce the duration of its appearance by putting these lines at the top of your script, which will also cause the flickering to happen only once the first time you call the cmd command. From https://autohotkey.com/board/topic/92032-how-to-hide-a-wscript-comspec-window/:
;Following 2 lines : the cmd window will flash only once and quickly
DllCall("AllocConsole")
WinHide % "ahk_id " DllCall("GetConsoleWindow", "ptr")
How about this script, StdoutToVar ?
It has support for 64bit consoles.
http://www.autohotkey.com/board/topic/15455-stdouttovar/page-7
This has been bugging me for some time now - and finally this works !
The only prerequisite for this is MS sqlcmd.exe, a database called AHK_Dev
and of course AHK_DBA to read the value when you wish to make use of it.
PS. make sure you replace {yourDir} and {yourServer} with you own values!
USE AHK_DEV
CREATE TABLE [dbo].[AHK_DOS]([dos_out] [varchar](max) NULL) ON [PRIMARY];
insert into ahk_dos select 'empty'
Create the follow script ... call it dos_out.bat
#echo off
if "%1" == "" (
set v_cmd=""
) else (
set v_cmd=%1
)
set v_cmd=%v_cmd:~1,-1%
SETLOCAL ENABLEDELAYEDEXPANSION
if "!v_cmd!" == "" (
set v_cmd="echo ... %COMPUTERNAME% %USERNAME% %DATE% %TIME%"
set v_cmd=!v_cmd:~1,-1!
)
set v_data=""
FOR /F "usebackq delims=¬" %%i in (`!v_cmd!`) do (
set v_data="!v_data:~1,-1!%%i~"
)
set q_cmd="set nocount on;update ahk_dos set dos_out=N'!v_data:~1,-1!'"
"{yourDir}\Microsoft SQL Server\90\Tools\Binn\sqlcmd.exe" -S {yourServer} -E -d ahk_dev -Q !q_cmd! -W
set q_cmd="set nocount on;select len(dos_out) as out_len, dos_out from ahk_dos"
"{yourDir}\Microsoft SQL Server\90\Tools\Binn\sqlcmd.exe" -S {yourServer} -E -d ahk_dev -Q !q_cmd! -W -w 8000
pause
you can run it from AHK using...
dosCmd2db(c) {
runwait, {yourDir\}dos_out.bat "%c%", , , dospid
msgbox %dospid% closed
}
dosCmd2db("")
dosCmd2db("echo This is a test")
dosCmd2db("dir")
As the same field is being updated each time, you would clearly need to do something between each one to make this example useful!
Try it, and let me know how you get on
Regards, Geoff
Just an update to #amynbe answer.
MsgBox % RunWaitOne("dir " A_ScriptDir)
RunWaitOne(command) {
shell := ComObjCreate("WScript.Shell")
exec := shell.Exec(ComSpec " /C " command)
return exec.StdOut.ReadAll() }
Note: the latter method (shell.Exec)
will cause quick display of a cmd window. You can reduce
> the duration of its appearance by putting these lines at the top of
> your script, which will also cause the flickering to happen only once
> the first time you call the cmd command.
You can just do this below to hide cmd and avoid flashing.
MsgBox % RunWaitOne("dir " A_ScriptDir)
RunWaitOne(command) {
DetectHiddenWindows On
Run %ComSpec%,, Hide, pid
WinWait ahk_pid %pid%
DllCall("AttachConsole", "UInt", pid)
shell := ComObjCreate("WScript.Shell")
exec := shell.Exec(ComSpec " /C " command)
DllCall( "FreeConsole" )
return exec.StdOut.ReadAll()
}
I found a script only solution that works for AutoHotKey L 64bit at:
http://www.autohotkey.com/board/topic/67687-ahkahk-lusing-wsh-to-interact-with-command-line-progs/
After playing with it a bit I was able to capthre the entire output of a 40k text file that I listed using the DOS Type command. There is a demo that shows how you can interact with time command, which is nice if you need limited two way interaction with a dos command or batch script.

Printing a web page from Windows Batch

Is it possible to use a windows batch script to open a web page and print its contents to your default printer? Something simple as this:
#echo off
start /d IEXPLORE.EXE www.google.com
and now I want to send that page to the printer. But I am not sure of the syntax nor was I able to find anything specific or helpful on the web.
Does anyone know if it's possible to print a web page using a windows batch command?
Not from an iexplore switch, but vbscript will work:
Const PRINT = 6
Const DONTPROMPTUSER = 2
Const BUSY=4
Dim oIExplorer
Set oIExplorer = CreateObject("InternetExplorer.Application")
oIExplorer.Navigate "http://www.stackoverflow.com/"
oIExplorer.Visible = 1
Do while oIExplorer.ReadyState <> BUSY
wscript.sleep 1000
Loop
oIExplorer.ExecWB PRINT, DONTPROMPTUSER

Resources