How can you create pop up messages in a batch script? - popup

I need to know how to make popup messages in batch scripts without using VBScript or KiXtart or any other external scripting/programming language.
I have zero clue about this... had no starting point even.
I am aware of NET SEND but the Messenger service is disabled in my current environment.

msg * "Enter Your Message"
Does this help ?

With regard to LittleBobbyTable's answer - NET SEND does not work on Vista or Windows 7. It has been replaced by MSG.EXE
There is a crude solution that works on all versions of Windows - A crude popup message can be sent by STARTing a new cmd.exe window that closes once a key is pressed.
start "" cmd /c "echo Hello world!&echo(&pause"
If you want your script to pause until the message box is dismissed, then you can add the /WAIT option.
start "" /wait cmd /c "echo Hello world!&echo(&pause"

You can take advantage of CSCRIPT.EXE or WSCRIPT.EXE (which have been present in every version of Windows since, I believe, Windows 95) like this:
echo msgbox "Hey! Here is a message!" > %tmp%\tmp.vbs
cscript /nologo %tmp%\tmp.vbs
del %tmp%\tmp.vbs
or
echo msgbox "Hey! Here is a message!" > %tmp%\tmp.vbs
wscript %tmp%\tmp.vbs
del %tmp%\tmp.vbs
You could also choose the more customizeable PopUp command. This example gives you a 10 second window to click OK, before timing out:
echo set WshShell = WScript.CreateObject("WScript.Shell") > %tmp%\tmp.vbs
echo WScript.Quit (WshShell.Popup( "You have 10 seconds to Click 'OK'." ,10 ,"Click OK", 0)) >> %tmp%\tmp.vbs
cscript /nologo %tmp%\tmp.vbs
if %errorlevel%==1 (
echo You Clicked OK
) else (
echo The Message timed out.
)
del %tmp%\tmp.vbs
In their above context, both cscript and wscript will act the same. When called from a batch file, bot cscript and wscript will pause the batch file until they finish their script, then allow the file to continue.
When called manually from the command prompt, cscript will not return control to the command prompt until it is finished, while wscript will create a seprate thread for the execution of it's script, returning control to the command prompt even before it's script has finished.
Other methods discussed in this thread do not cause the execution of batch files to pause while waiting for the message to be clicked on. Your selection will be dictated by your needs.
Note: Using this method, multiple button and icon configurations are available to cover various yes/no/cancel/abort/retry queries to the user: https://technet.microsoft.com/en-us/library/ee156593.aspx

Few more ways (in all of them the script waits for button pressing unlike msg.exe).
1) The geekiest and hackiest - it uses the IEXPRESS to create small exe that will create a pop-up with a single button (it can create two more types of pop-up messages).Works on EVERY windows from XP and above:
;#echo off
;setlocal
;set ppopup_executable=popupe.exe
;set "message2=%~1"
;
;del /q /f %tmp%\yes >nul 2>&1
;
;copy /y "%~f0" "%temp%\popup.sed" >nul 2>&1
;(echo(FinishMessage=%message2%)>>"%temp%\popup.sed";
;(echo(TargetName=%cd%\%ppopup_executable%)>>"%temp%\popup.sed";
;(echo(FriendlyName=%message1_title%)>>"%temp%\popup.sed"
;
;iexpress /n /q /m %temp%\popup.sed
;%ppopup_executable%
;rem del /q /f %ppopup_executable% >nul 2>&1
;pause
;endlocal
;exit /b 0
[Version]
Class=IEXPRESS
SEDVersion=3
[Options]
PackagePurpose=InstallApp
ShowInstallProgramWindow=1
HideExtractAnimation=1
UseLongFileName=0
InsideCompressed=0
CAB_FixedSize=0
CAB_ResvCodeSigning=0
RebootMode=N
InstallPrompt=%InstallPrompt%
DisplayLicense=%DisplayLicense%
FinishMessage=%FinishMessage%
TargetName=%TargetName%
FriendlyName=%FriendlyName%
AppLaunched=%AppLaunched%
PostInstallCmd=%PostInstallCmd%
AdminQuietInstCmd=%AdminQuietInstCmd%
UserQuietInstCmd=%UserQuietInstCmd%
SourceFiles=SourceFiles
[SourceFiles]
SourceFiles0=C:\Windows\System32\
[SourceFiles0]
%FILE0%=
[Strings]
AppLaunched=subst.exe
PostInstallCmd=<None>
AdminQuietInstCmd=
UserQuietInstCmd=
FILE0="subst.exe"
DisplayLicense=
InstallPrompt=
;
Example Usage (if you save the script as expPopup.bat):
call expPopup.bat "my Message"
2) Using MSHTA. Also works on every windows machine from XP and above (despite yhe OP do not wants "external" languages the jsvascript here is minimized).Should be saved as .bat:
#if (true == false) #end /*!
#echo off
mshta "about:<script src='file://%~f0'></script><script>close()</script>" %*
goto :EOF */
alert("Hello, world!");
or in one line:
mshta "about:<script>alert('Hello, world!');close()</script>"
or
mshta "javascript:alert('message');close()"
or
mshta.exe vbscript:Execute("msgbox ""message"",0,""title"":close")
3) Here's parametrized .bat/jscript hybrid (should be saved as bat) .It again uses jscript despite the OP request but as it is a bat it can be called as a bat file without worries.It uses POPUP which allows a little bit more control than the more populae MSGBOX.It uses WSH ,but not MSHTA like in the example above.
#if (#x)==(#y) #end /***** jscript comment ******
#echo off
cscript //E:JScript //nologo "%~f0" "%~nx0" %*
exit /b 0
#if (#x)==(#y) #end ****** end comment *********/
var wshShell = WScript.CreateObject("WScript.Shell");
var args=WScript.Arguments;
var title=args.Item(0);
var timeout=-1;
var pressed_message="button pressed";
var timeout_message="timedout";
var message="";
function printHelp() {
WScript.Echo(title + "[-title Title] [-timeout m] [-tom \"Time-out message\"] [-pbm \"Pressed button message\"] [-message \"pop-up message\"]");
}
if (WScript.Arguments.Length==1){
runPopup();
WScript.Quit(0);
}
if (args.Item(1).toLowerCase() == "-help" || args.Item(1).toLowerCase() == "-h" ) {
printHelp();
WScript.Quit(0);
}
if (WScript.Arguments.Length % 2 == 0 ) {
WScript.Echo("Illegal arguments ");
printHelp();
WScript.Quit(1);
}
for (var arg = 1 ; arg<args.Length;arg=arg+2) {
if (args.Item(arg).toLowerCase() == "-title") {
title = args.Item(arg+1);
}
if (args.Item(arg).toLowerCase() == "-timeout") {
timeout = parseInt(args.Item(arg+1));
if (isNaN(timeout)) {
timeout=-1;
}
}
if (args.Item(arg).toLowerCase() == "-tom") {
timeout_message = args.Item(arg+1);
}
if (args.Item(arg).toLowerCase() == "-pbm") {
pressed_message = args.Item(arg+1);
}
if (args.Item(arg).toLowerCase() == "-message") {
message = args.Item(arg+1);
}
}
function runPopup(){
var btn = wshShell.Popup(message, timeout, title, 0x0 + 0x10);
switch(btn) {
// button pressed.
case 1:
WScript.Echo(pressed_message);
break;
// Timed out.
case -1:
WScript.Echo(timeout_message);
break;
}
}
runPopup();
example usage (it will wait 10 seconds to press the yes button):
jsPopup.bat -title CoolTitile -t 10 -tom "time out" -pbm "press the button please" -message "love and peace"
4) and one jscript.net/.bat hybrid (should be saved as .bat) .This time it uses .NET and compiles a small .exe file that could be deleted:
#if (#X)==(#Y) #end /****** silent jscript comment ******
#echo off
::::::::::::::::::::::::::::::::::::
::: compile the script ::::
::::::::::::::::::::::::::::::::::::
setlocal
::if exist "%~n0.exe" goto :skip_compilation
:: searching the latest installed .net framework
for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
if exist "%%v\jsc.exe" (
rem :: the javascript.net compiler
set "jsc=%%~dpsnfxv\jsc.exe"
goto :break_loop
)
)
echo jsc.exe not found && exit /b 0
:break_loop
call %jsc% /nologo /out:"%~n0.exe" "%~f0"
::::::::::::::::::::::::::::::::::::
::: end of compilation ::::
::::::::::::::::::::::::::::::::::::
:skip_compilation
::
::::::::::
"%~n0.exe" %*
::::::::
::
endlocal
exit /b 0
****** end of jscript comment ******/
import System;
import System.WIndows;
import System.Windows.Forms
var arguments:String[] = Environment.GetCommandLineArgs();
MessageBox.Show(arguments[1],arguments[0]);
Example usage:
netPopUp.bat "Roger That"
5) and at the end one single call to powershell that creates a pop-up (can be called from command line or from batch if powershell is installed):
powershell [Reflection.Assembly]::LoadWithPartialName("""System.Windows.Forms""");[Windows.Forms.MessageBox]::show("""Hello World""", """My PopUp Message Box""")
6) Though msg solution is already post as answer here's a better way to be used:
msg * /self /w "hello world"
/self is a not documented switch that will force msg to send the message only to the current user.

msg * Hello world
works for me..

So, i present cmdmsg.bat.
The code is:
#echo off
echo WScript.Quit MsgBox(%1, vbYesNo) > #.vbs
cscript //nologo #.vbs
echo. >%ERRORLEVEL%.cm
del #.vbs
exit /b
And a example file:
#echo off
cls
call cmdmsg "hi select yes or no"
if exist "6.cm" call :yes
if exist "7.cm" call :no
:yes
cls
if exist "6.cm" del 6.cm
if exist "7.cm" del 7.cm
echo.
echo you selected yes
echo.
pause >nul
exit /b
:no
cls
if exist "6.cm" del 6.cm
if exist "7.cm" del 7.cm
echo.
echo aw man, you selected no
echo.
pause >nul
exit /b

I put together a script based on the good answers here & in other posts
You can set title timeout & even sleep to schedule it for latter & \n for new line
also you get back the key press into a variable (%pop.key%).
Here is my code

Your best bet is to use NET SEND as documented on Rob van der Woude's site.
Otherwise, you'll need to use an external scripting program. Batch files are really intended to send messages via ECHO.

This is very simple beacuse i have created a couple lines of code that will do this for you
So set a variable as msg and then use this code. it popup in a VBS message box.
CODE:
#echo off
echo %msg% >vbs.txt
copy vbs.txt vbs.vbs
del vbs.txt
start vbs.vbs
timeout /t 1
del vbs.vbs
cls
This is just something i came up with it should work for most of your message needs and it also works with Spaces unlike some batch scripts

It's easy to make a message, here's how:
First open notpad and type:
msg "Message",0,"Title"
and save it as Message.vbs.
Now in your batch file type:
Message.vbs %*

msg * message goes here
That method is very simple and easy and should work in any batch file i believe. The only "downside" to this method is that it can only show 1 message at once, if there is more than one message it will show each one after the other depending on the order you put them inside the code. Also make sure there is a different looping or continuous operator in your batch file or it will close automatically and only this message will appear. If you need a "quiet" background looping opperator, heres one:
pause >nul
That should keep it running but then it will close after a button is pressed.
Also to keep all the commands "quiet" when running, so they just run and dont display that they were typed into the file, just put the following line at the beginning of the batch file:
#echo off
I hope all these tips helped!

Related

Mikrotik - result of script job as var is empty

I need to now some info about LTE/3G connection from output of command with Zabbix. Routerboard is 6.47.7 version.
[admin#Mikrotik_24] > interface lte info lte1 once
pin-status: ok
registration-status: registered
functionality: full
manufacturer: "MikroTik"
model: "R11e-LTE"
revision: "MikroTik_CP_2.160.000_v008"
current-operator: MTS
psc: 295
lac: 5205
current-cellid: 241903616
access-technology: 3G
session-uptime: 21h3m18s
imei: 355654090621868
imsi: 250016652966098
uicc: 89701011266529660988
earfcn: 10762
ecno: 0dB
rssi: -95dBm
For example "rssi", "access-technology", "uicc" and so on.
The problem with such command described by themselves - the data goes infinitely, and you cant catch it easy.
https://wiki.mikrotik.com/wiki/Manual:Scripting_Tips_and_Tricks#Get_values_from_looped_interactive_commands_like_.22monitor.22
So I have a script to get some values as a global var.
/interface lte info lte1 once do={:global at $"access-technology" }
and ":put $at" in terminal works fine. But I think to take result with SNMP by executing another script to show this generated var $at. It is possible with OID they did for "script result" purpose.
The question is how to output this var in script?
[admin#Mikrotik_24] > /system script export compact
# oct/31/2020 01:52:57 by RouterOS 6.47.7
# software id = PW8X-NNQ5
#
# model = RouterBOARD wAP R-2nD
/system script
add dont-require-permissions=no name=at owner=admin policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\
"/interface lte info lte1 once do={:global at \$\"access-technology\" } \r\
\n"
add dont-require-permissions=no name=at_result owner=admin policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":put \$at"
[admin#Mikrotik_24] > :environment print
at="3G"
[admin#Mikrotik_24] > /system script environment print
# NAME VALUE
0 at 3G
[admin#Mikrotik_24] > /system script run at_result
[admin#Mikrotik_24] >
You see, /system script run at_result is empty, but in terminal I can see it
[admin#Mikrotik_24] > :put $at
3G
[admin#Mikrotik_24] >
Ok. The right form of script var is
{
:global test
set $test "my data"
}
I have to declare it first.

AutomationFocusChangedEventHandler: event dose not triggerd in powershell

I'm traying to detect focus change using a powershell script, hier is my code
start calc
Write-Host "Loading MS UIA assemblies"
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClient")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationTypes")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationProvider")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClientsideProviders")
try
{
# WORKAROUND: There is a weird bug: first call fails ...
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
}
catch {}
# ... second call succeeds:
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
$focusedElem = [Windows.Automation.AutomationElement]::FocusedElement #this one work fine
Write-Host "name: " $focusedElem.Current.Name
Write-Host "ControlType: " $focusedElem.Current.ControlType
Write-Host "ProcessId: " $focusedElem.Current.ProcessId
$onFocusChange = { # this dose not fired !!!!
param([Sytem.Object]$src, [Windows.Automation.AutomationFocusChangedEventArgs]$e)
start notepad
}
$focusChangeHandler = [Windows.Automation.AutomationFocusChangedEventHandler]($onFocusChange)
[Windows.Automation.Automation]::AddAutomationFocusChangedEventHandler($focusChangeHandler)
Start-Sleep -Seconds 5 #durring this sleep i change the focused window, but nothing happen :(
[Windows.Automation.Automation]:: RemoveAutomationFocusChangedEventHandler($focusChangeHandler)
any idea why this script not working, or any idea how to monitoring focus change in powershell without external tools ?

Windows batch file check time and date then rename [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I need to rename todays date paymentpagecalls20200128.txt and WithdrawalConfirm20200128.txt to paymentpagecalls20200129_*time*.txtand WithdrawalConfirm20200129_*time*.txt when it is every 8 hours or if possible 12:00am/6:00am/10:00PM.
I have this code to get my time ( just copied it to some of my searched )
set "destination=C:\Users\JBP-Admin\Desktop\Pugad\Forback_UP\Destination"
set day=0
echo >"%temp%\%~n0.vbs" s=DateAdd("d",%day%,now) : d=weekday(s)
echo>>"%temp%\%~n0.vbs" WScript.Echo year(s)^& right(100+month(s),2)^& right(100+day(s),2)
for /f %%a in ('cscript /nologo "%temp%\%~n0.vbs"') do set "result=%%a"
del "%temp%\%~n0.vbs"
set "YYYY=%result:~0,4%"
set "MM=%result:~4,2%"
set "DD=%result:~6,2%"
set "result=%yyyy%%mm%%dd%"
echo %result%
for /r "C:\Users\JBP-Admin\Desktop\Pugad\For Rename" %%G in (*%result%.txt) do (
ren "%%~fG" "C:\Users\JBP-Admin\Desktop\Pugad\For Rename"
if exist "C:\Users\JBP-Admin\Desktop\Pugad\For Rename%%~nxG" (
echo File "%%~fG" renamed successfully.
) else (
echo File "%%~fG" renamed failed.
)
)
pause
how can I insert the part to check the time then rename it?
Break down of what's happening
Retreive all .txt files from said directory that match given criteria
We parse the filenames and extract the existing date and append the new date
Rename the file(s)
The output of this which is an ".exe" can be scheduled in task
scheduler to executed at given interval based on given condition.
Go to TaskScheduler > Action > Create Basic Task > Set Trigger, Action > Finish
using System;
using System.IO;
using System.Linq;
namespace Test
{
public class Program
{
static void Main(string[] args)
{
string FolderPath = #"C:\Users\John\Documents";
DirectoryInfo di = new DirectoryInfo(FolderPath);
var files = di.EnumerateFiles("*.txt")
.Where(s => s.Name.Contains("Withdrawal")
|| s.Name.Contains("payment")).ToList();
var Currentfile1 = files[0].FullName;
var Currentfile2 = files[1].FullName;
//Parsing files
var Newfile1 = Currentfile1.Substring(0, Currentfile1.Length - 2);
var Newfile2 = Currentfile2.Substring(0, Currentfile2.Length - 2);
// Append new date
Newfile1 = Newfile1 + DateTime.Now.ToString("yyyyMMdd") + ".txt";
Newfile2 = Newfile2 + DateTime.Now.ToString("yyyyMMdd") + ".txt";
//Rename
File.Move(Currentfile1, Newfile1);
File.Move(Currentfile2, Newfile2);
}
}
}

How to kick off ExtendScript JSX script from Powershell

I want to be able to execute an Adobe Illustrator ExtendScript via Windows Powershell. I believe this should be possible due to this answer that describes using VB via COM.
This is my Powershell script:
$illustratorRef = New-Object -ComObject Illustrator.Application
$conversionScript = New-Object -ComObject Scripting.FileSystemObject
$scriptFile = $conversionScript.OpenTextFile("C:\ws\ArtConversion\alert-test.jsx")
$fileContents = $scriptFile.ReadAll()
$scriptFile.Close()
$fileToRun = $fileContents + "main(arguments)"
$args = "line1", "line2"
$illustratorRef.DoJavaScript($fileToRun, $args, 1)
Here is the alert-test.jsx script:
function main(argv) {
alert('message: ' + argv[0]);
return argv[0];
}
Running the Powershell script opens Illustrator, but throws the following error upon encountering $illustratorRef.DoJavaScript:
Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))
I am using Adobe Illustrator 2019 CC (64bit) and Powershell 5.1.16299.666
I achieved my goal, but wasn't able to do it 100% with Powershell.
The 2017 Adobe Illustrator Scripting Guide contains this statement on page 22:
In VBScript, there are several ways to create an instance of Illustrator.
When referring to JavaScript however, it says:
Information on launching Illustrator from JavaScript is beyond the scope of this guide.
I couldn't find any official documentation on how to programmatically start Illustrator on Windows using other languages besides VB, so I ended up letting my Powershell script handle the heavy lifting of directory traversal and logging, while having it open Illustrator by means of a Visual Basic script.
The call from Powershell into VB looks like this:
$convertFile = "cmd /C cscript .\run-illustrator-conversion.vbs $arg1, $arg2"
$output = Invoke-Expression $convertFile
The VB script ended up looking like this:
Dim appRef
Dim javaScriptFile
Dim argsArr()
Dim fsObj : Set fsObj = CreateObject("Scripting.FileSystemObject")
Dim jsxFile : Set jsxFile = fsObj.OpenTextFile(".\script-to-run.jsx", 1, False)
Dim fileContents : fileContents = jsxFile.ReadAll
jsxFile.Close
Set jsxFile = Nothing
Set fsObj = Nothing
javascriptFile = fileContents & "main(arguments);"
Set appRef = CreateObject("Illustrator.Application.CS5")
ReDim argsArr(Wscript.Arguments.length - 1)
For i = 0 To Wscript.Arguments.length - 1
argsArr(i) = Wscript.Arguments(i)
Next
Wscript.Echo appRef.DoJavaScript(javascriptFile, argsArr, 1)
Note: Check scripting guide to get correct string for your version of Illustrator.

F# Run Powershell Script As Target

Trying to run a powershell script using F# FAKE but nothing happens... there are no errors, the target loads but nothing actually is run.
// include Fake lib
#r "packages/FAKE/tools/FakeLib.dll"
#r "System.Management.Automation"
open System
open System.IO
open System.Diagnostics
open System.Management.Automation
Target "Powershell" <| fun _ ->
PowerShell.Create()
.AddScript("& 'build-database.ps1'")
.AddParameter("BuildVersion", version)
.AddParameter("Debug", "")
.Invoke()
|> Seq.iter (printfn "%O")
// Dependencies
"Clean"
==> "Powershell"
// start build
RunTargetOrDefault "Powershell"
Am I missing something? Without any error I am not sure what the issue is.
* Updated *
This is the powershell script I am testing with, FAKE does nothing.
New-Item c:\AnEmptyFile.txt -ItemType file
I finally figured out another way to do it that works. In case someone else has the need to call a powershell script from within F# FAKE the following method worked for me.
Target "Powershell" (fun _ ->
let p = new System.Diagnostics.Process();
p.StartInfo.FileName <- "cmd.exe";
p.StartInfo.Arguments <- ("/c powershell -ExecutionPolicy Unrestricted .\\script.ps1)
p.StartInfo.RedirectStandardOutput <- true
p.StartInfo.UseShellExecute <- false
p.Start() |> ignore
printfn "Processing..."
printfn "%A" (p.StandardOutput.ReadToEnd())
printfn "Finished"
)
Its possible to use Shell.Execute and invoke powershell.exe:
Target "ImportDb" (fun _ ->
Shell.Exec("powershell.exe", "-NoProfile -ExecutionPolicy Bypass -File script.ps1") |> ignore)