You can call me insane but I did it and would like to share it with you.
The idea and first implementation have appeared few years ago. Initially I was needed to forward output of some commands directly into my favorite browser. During all this time it was improved many times (become simplified, complicated and simplified again). Now it still works properly and I don't see ways to simplify it without loosing flexibility.
There is script doing very simple work -- it captures STDOUT of some command to a temporary file and launches some GUI application with this file. in the other words, it mimics other command line tools and opens output of commands in GUI application.
Explanation
Definitely, I am slightly mad. The essential code is very simple. Because GUI is not able to read STDIN (I guess there could be such a kind of GUIs, but the majority of them cannot). So we just store output to some file and open it in some application:
Code: Select all
command > tempfile
guiapp tempfile
The rest of the script (over 260 lines in total, over 100 lines of pure code) is needed to make the script flexible and configurable as much as possible.
Examples
Running without options it always invokes notepad:
Code: Select all
echo:Hello, world | 2
Let's see the same text in an another application, for example in the default browser (usually MSIE)
Code: Select all
echo:Hello, world | 2 html
Let's see now the same text in another browser. Assume we have two browsers in the system MSIE as default one and the another one (let say, Firefox). Create the file 2.html.bat. Once we have this configuration file, we are able to change the application
Code: Select all
:: Set the extension to recognize the data type
set "pipeext=.html"
:: Mozilla Command Line Options
:: https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options
::
:: firefox -h | more
set "pipecmd="%ProgramFiles%\Firefox\firefox.exe" %%*"
If you need to change behavior of the application, you can launch it with an another extension. So the following example invokes the browser (as it is defined in 2.html.bat) and says to assume data as a plain text file (.txt extension).
Code: Select all
echo:Hello world | 2 html.txt
It supports few options:
Code: Select all
-d DIR use DIR for storing temp files
-n NAME use NAME as the name of temp file
--debug turn on debug information
--dry-run don't invoke a command, display only
Source
Source code is available in the attached file and following by the link:
https://github.com/ildar-shaimordanov/t ... /bin/2.bat
https://github.com/ildar-shaimordanov/t ... 2.html.bat
Code: Select all
::HELP Redirects output of command line tools to GUI application.
::HELP
::HELP
::HELP USAGE
::HELP
::HELP command | 2 [OPTIONS] [APP[.EXT] | EXT] [APP-OPTIONS]
::HELP
::HELP
::HELP OPTIONS
::HELP
::HELP -d DIR use DIR for storing temp files
::HELP -n NAME use NAME as the name of temp file
::HELP --debug turn on debug information
::HELP --dry-run don't invoke a command, display only
::HELP
::HELP
::HELP DESCRIPTION
::HELP
::HELP The script is flexible enough to enable many ways to invoke GUI
::HELP applications. Which GUI application would be invoked is defined by
::HELP the arguments. Depending on what is this, it will be called to
::HELP declare few specific environment variables.
::HELP
::HELP
::HELP INVOCATION
::HELP
::HELP commands | 2
::HELP
::HELP With no parameters runs Notepad. Always.
::HELP
::HELP commands | 2 APP
::HELP
::HELP "APP" is the parameter defining an application or a family of
::HELP applications or an extension (without the leading "dot" symbol).
::HELP The script looks around for the file called as "2.APP.bat". If the
::HELP file exists, invokes it to set the needful environment variables.
::HELP The script should declare few specific environment variables (see
::HELP the "ENVIRONMENT" section below).
::HELP
::HELP commands | 2 APP.EXT
::HELP
::HELP The same as above but ".EXT" overrides early declared extension.
::HELP
::HELP commands | 2 EXT
::HELP
::HELP If there is no file "2.APP.bat", the argument is assumed as the
::HELP extension (without the leading "dor" symbol), the script does
::HELP attempt to find an executable command (using "assoc" and "ftype")
::HELP and prepare invocation of the command found by these commands.
::HELP
::HELP
::HELP ENVIRONMENT
::HELP
::HELP %pipecmd%
::HELP
::HELP (Mandatory)
::HELP Invocation string for the application. It could or could not
::HELP contain additional parameters supported by the application.
::HELP
::HELP %pipeext%
::HELP
::HELP (Optional, but recommended to set)
::HELP Extenstion (like ".txt" or ".html" etc). It can be useful in the
::HELP case if the application is able to handle different data files.
::HELP
::HELP %pipetmpsave%
::HELP
::HELP (Optional)
::HELP The command line tool used for capturing output of commands and
::HELP redirecting to a resulting file. By default it is set as follows:
::HELP
::HELP set "pipetmpsave=more"
::HELP
::HELP Another possible setting is:
::HELP
::HELP set "pipetmpsave=findstr "$""
::HELP
::HELP
::HELP CONFIGURATION
::HELP
::HELP Using the file "2-settings.bat" located in the same directory
::HELP allows to configure the global environment variables of the main
::HELP script. It is good place for setting such kind of variables as
::HELP %pipetmpdir%, %pipetmpname% and %pipetmpsave%.
::HELP
::HELP
::HELP SEE ALSO
::HELP
::HELP ASSOC /?
::HELP FTYPE /?
:: ========================================================================
@echo off
timeout /t 0 >nul 2>&1 && (
call :pipe-help
goto :EOF
)
:: ========================================================================
setlocal
set "pipedbg="
set "pipedry="
set "pipetmpdir=%TEMP%"
set "pipetmpname=pipe.%RANDOM%"
set "pipetmpfile="
set "pipetmpsave=more"
if exist "%~dpn0-settings.bat" call "%~dpn0-settings.bat"
set "pipecmd="
set "pipecmdopts="
set "pipetitle="
set "pipeext="
:: ========================================================================
:pipe-options-begin
if "%~1" == "" goto :pipe-options-end
if "%~1" == "-d" (
set "pipetmpdir=%~2"
shift /1
shift /1
) else if "%~1" == "-n" (
set "pipetmpname=%~2"
shift /1
shift /1
) else if "%~1" == "--debug" (
set "pipedbg=1"
shift /1
) else if "%~1" == "--dry-run" (
set "pipedry=1"
shift /1
) else (
goto :pipe-options-end
)
goto :pipe-options-begin
:pipe-options-end
:: ========================================================================
if "%~1" == "" (
rem command | 2
set "pipecmd=notepad"
set "pipetitle=[app = notepad]"
set "pipeext=.txt"
) else if exist "%~dpn0.%~n1.bat" (
rem command | 2 app[.ext]
call :pipe-configure "%~dpn0.%~n1.bat" "%~x1"
set "pipetitle=[app = %~n1]"
if not defined pipeext set "pipeext=%~n1"
if not "%~x1" == "" set "pipeext=%~x1"
shift /1
) else (
rem command | 2 ext
for /f "tokens=1,* delims==" %%a in ( '
2^>nul assoc ".%~n1"
' ) do for /f "tokens=1,* delims==" %%c in ( '
2^>nul ftype "%%b"
' ) do (
set "pipecmd=%%d"
set "pipetitle=[%%a = %%b]"
set "pipeext=%%a"
)
if not "%~x1" == "" set "pipeext=%~x1"
shift /1
)
if defined pipedbg call :pipe-debug "After parsing options"
:: ========================================================================
if not defined pipecmd (
>&2 echo:Bad invocation
goto :EOF
)
:: ========================================================================
if not defined pipeext set "pipeext=.txt"
if not defined pipetitle set "pipetitle=[%pipeext%]"
for %%f in ( "%pipetmpdir%" ) do set "pipetmpfile=%%~ff\%pipetmpname%%pipeext%"
:: ========================================================================
setlocal enabledelayedexpansion
set "pipecmdopt="
:pipe-app-options-begin
set pipecmdopt=%1
if not defined pipecmdopt goto :pipe-app-options-end
set "pipecmdopts=%pipecmdopts% %pipecmdopt%"
shift /1
goto :pipe-app-options-begin
:pipe-app-options-end
set "pipecmd=!pipecmd:%%1="%%1"!"
set "pipecmd=!pipecmd:""%%1""="%%1"!"
if "!pipecmd!" == "!pipecmd:%%1=!" set "pipecmd=!pipecmd! "%%1""
set "pipecmd=!pipecmd:%%1=%pipetmpfile%!"
endlocal & set "pipecmd=%pipecmd%" & set "pipecmdopts=%pipecmdopts%"
:: ========================================================================
if defined pipedbg call :pipe-debug "Before invocation"
call :pipe-invoke %pipecmdopts%
endlocal
goto :EOF
:: ========================================================================
:pipe-configure
setlocal
call "%~1" "%~2"
endlocal & set "pipecmd=%pipecmd%" & set "pipeext=%pipeext%" & set "pipetmpsave=%pipetmpsave%"
goto :EOF
:pipe-invoke
if defined pipedry (
echo:Invocation ^(dry-run^)
echo:call %pipetmpsave% ^> "%pipetmpfile%"
echo:call start "Starting %pipetitle%" %pipecmd%
goto :EOF
)
call %pipetmpsave% > "%pipetmpfile%"
call start "Starting %pipetitle%" %pipecmd%
goto :EOF
:: ========================================================================
:pipe-help
for /f "tokens=1,* delims= " %%a in ( '
findstr /b "::HELP" "%~f0"
' ) do (
echo:%%~b
)
goto :EOF
:pipe-debug
echo:%~1...
set pipe
echo:
goto :EOF
:: ========================================================================
:: EOF