special char redirection without quotes

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

special char redirection without quotes

Post by MigrationUser »

15 Jul 2011 11:56
allal

how to redirect a string which contain "&,>,|" to a file without using quotes
because i don't want my output in the output file to be surrounded by quotes
i want it to be like the original file redireted from
example

Code: Select all

for /f "tokens=*" %%G IN (file.txt) do (
  REM consider the current line contains ampersand and must not be surrounded by quotes in the output 
  ECHO %%G >> output.txt
)


output

'your redirected string' is not recognized as an internal or external command,operable program or batch file.


output wanted in the output file

whatever string to redirect & your redirected string

NOT

"whatever string to redirect & your redirected string"

Last edited by allal (15 Jul 2011 16:06)

----------------------------

#2 15 Jul 2011 17:54
jeb


This can't be the problem if you work with XP, Vista or Win7,
as the expansion of %%G is secure against any special characters,
the only problems you can get there, are with exclamation marks and carets if the DelayeDexpansionEnable is active.

I suppose your code creates this problem at another line.

jeb

----------------------------

#3 15 Jul 2011 20:55
allal


once again seems that cmd alone can not do it
cmd must take advantage of available built-in scripting language too (required)

i have just noticed that vb,jscript will remove the surrounding quotes when echoing lines
so if you want to echo one double surrounding quotes you need three double quotes
and that is exacly what i want

Code: Select all

set "line1={whatever string to redirect & your redirected string}"
set "line2=string (contain poison chars) || yo&&ur"

call :printfile "%line1%" "%line2%" "%temp%\outfile.txt"
goto ;eof

:Printfile <line1> <line2> <outfile:In>  -- Append two lines to one file at once
setlocal
> "%temp%\write.vbs" (
    echo Const ForAppending = 8

    echo Set objFSO = CreateObject("Scripting.FileSystemObject"^)
    echo Set objFile = objFSO.OpenTextFile("%~3", ForAppending,True^)
    echo objFile.writeline "%~1% %~2"
    echo objFile.close
)    
    for /f %%G IN ('cscript //nologo "%temp%\write.vbs"') do del "%temp%\write.vbs"
    endlocal &exit/b
output without quotes:

{whatever string to redirect & your redirected string} string (contain) || yo&&ur

Last edited by allal (15 Jul 2011 21:35)

----------------------------

#4 17 Jul 2011 10:07
flabdablet


The way cmd handles quotes and escaping is broken and wrong, and conspires with the order in which parameter and variable expansions occur to cause endless grief.

Variable expansion inline using %name% happens very early, leaving the expanded value subject to interpretation by the parser. And because quotes get carried around in values, there's no reliable way to force the parser to leave that value uninterpreted. Simply wrapping an expansion in quotes (e.g. "%name%") doesn't work if the value itself contains quotes; it merely adds unwanted cruft.

Parameter expansion using %1 etc. happens even earlier. This means that there's no fully safe way to pass a variable's value (as opposed to its name) to a subroutine.

Delayed expansion using !name! is better, because it happens after all the line termination and redirection operators have already been processed. It's still not perfect, though, as it deletes any ! characters that may be inside the value. Why? Don't know. (edit: this is not true. See later messages from jeb.)

The only 100%-safe variable expansion method I know of is parsing the output of SET using a FOR command, and then using FOR-variable expansion inside the command line where you need the expanded value, like this:

Code: Select all

set poison="^"^)^&^|^>^<%%

call :echo poison
echo %poison%
echo "%poison%"
echo done
goto :eof

:echo
for /f "tokens=1,* delims==" %%A in ('set %1') do if "%%A" == "%1" (
    echo %%B
)
goto :eof
Here's the result of saving that code as foo.cmd and running it:

Code: Select all

N:\>foo

N:\>set poison="^")&|><%

N:\>call :echo poison

N:\>for /F "tokens=1,* delims==" %A in ('set poison') do if "%A" == "poison" (echo %B )

N:\>if "poison" == "poison" (echo "^")&|><% )
"^")&|><%
| was unexpected at this time.

N:\>echo "^")&|><%

N:\>
Note in particular that neither echo %poison% nor echo "%poison%" works as intended; in fact, the first one encountered actually breaks script execution (you should swap them around to verify this).

Note also that if your value is already inside a FOR pseudo-variable rather than an environment variable (as it will be in the body of for /f "tokens=*" %%G in (file.txt)) then you don't need to jump through hoops to expand it safely.

Last edited by flabdablet (20 Jul 2011 18:00)

----------------------------

#5 17 Jul 2011 10:27
flabdablet


Here's a safe version of your :Printfile subroutine using these principles:

Code: Select all

set "line1={whatever string to redirect & your redirected string}"
set "line2=string (contain poison chars) || === yo&&ur"

call :printfile line1 line2 "%temp%\outfile.txt"
goto :eof

:Printfile
for /f "tokens=1,* delims==" %%A in ('set %1') do if "%%A" == "%1" (
    for /f "tokens=1,* delims==" %%C in ('set %2') do if "%%C" == "%2" (
        echo %%B %%D>>"%~3"
    )
)
goto :eof
And the output from %temp%\outfile.txt:

Code: Select all

{whatever string to redirect & your redirected string} string (contain poison chars) || === yo&&ur
----------------------------

#6 17 Jul 2011 10:27
RG


Clever! Interesting approach. However even that is broken by the % sign.
Note that the second % does not appear in the output.
Also, placing a % somewhere else in the string causes problems.

Windows Shell Scripting and InstallShield

----------------------------

#7 17 Jul 2011 18:21
allal


thanks flabdablet i never thought cmd can do it,however you should always be careful of the existance of % or ! in a string
the problem of exclamation mark in a string can be solved and there are a lot of workarround about it but the percent sign is a pain
since the problem of poison character exist only in cmd you should always test for them before proceding

Code: Select all

@echo off &setlocal
echo %*|findstr [%%!] && (
call :vbs,jscript,powershell) || call :cmd


and if it is the case and you were lucky testing for the percent sign then use other scripting language from cmd or use vb,js or powershell directly to guarranty 100% a correct output
the cmd expansion rules make it impossible to always guaranty a correct output
it still if you insist to use other language from cmd when detecting that the string contain percent sign and you know how much they are then you need to double 1 percent sign eight times for other scripting language to get 1

if you want i will show you my ultimate method that deal with percent sign in a string

Code: Select all

@echo off &setlocal
echo %*|findstr [%%] && (
     echo percent sign is detected
     working with percent sign in strings in cmd is not supported
     pause&goto :eof
)
___________________________________________________________________________________

http://ss64.org/oldforum/viewtopic.php?id=1255

----------------------------

#8 18 Jul 2011 09:32
jeb


Hi flabdablet,
flabdablet wrote:

The way cmd handles quotes and escaping is broken and wrong, and conspires with the order in which parameter and variable expansions occur to cause endless grief.
It isn't broken, it's only a bit complex and undocumented.
flabdablet wrote:

Variable expansion inline using %name% happens very early, leaving the expanded value subject to interpretation by the parser. And because quotes get carried around in values, there's no reliable way to force the parser to leave that value uninterpreted. Simply wrapping an expansion in quotes (e.g. "%name%") doesn't work if the value itself contains quotes; it merely adds unwanted cruft.
You are right, the percent expansion happens very early,
but even if the rest is interpreted, it's possible to build a "secure" string even with quotes.
flabdablet wrote:

Parameter expansion using %1 etc. happens even earlier. This means that there's no fully safe way to pass a variable's value (as opposed to its name) to a subroutine.
%1 and %variable% expansion is executed at the same time, but I confirm that there isn't a safe way (with acceptable complexity) to pass variables to a subroutine.
It's possible, but it's too complex/slow for normal usage, I only use it to access the parameters for the batch file itself.
flabdablet wrote:

Delayed expansion using !name! is better, because it happens after all the line termination and redirection operators have already been processed. It's still not perfect, though, as it deletes any ! characters that may be inside the value. Why? Don't know.
No. It doesn't delete any exclamation marks nor carets, it only appears so.
Normally this is only an effect while setting the variables. Not while expanding.

Code: Select all

@echo off
setlocal DisableDelayedExpansion
set "var1=&|<>!%% one ^ caret"
setlocal EnableDelayedExpansion
set "var2=&|<>^!%% one ^^ caret"
echo one  !var1!
echo two  !var2!
set var
The result is always
&|<>!% one ^ caret
flabdablet wrote:

The only 100%-safe variable expansion method I know of is parsing the output of SET using a FOR command, and then using FOR-variable expansion inside the command line where you need the expanded value, like this:
Delayed Expansion is absolutly secure,
FOR-Variable expansion is only secure if delayed expansion is disabled, but then you can't work with the content.
The best way seems to be the DelayedExpansion-Toggling technic.

This sample reads a file with any content and replace all "a" with "b" and echo the result, it can handle any special characters.

Code: Select all

setlocal DisableDelayedExpansion
for /F "delims=" %%a in (myFile.txt) DO (
  set "line=%%a"
  setlocal EnableDelayedExpansion
  set "line=!line:a=b!"
  echo(!line!
  endlocal
)
jeb

----------------------------

#9 18 Jul 2011 10:18
flabdablet
RG wrote:

Clever! Interesting approach. However even that is broken by the % sign.
Note that the second % does not appear in the output.
Also, placing a % somewhere else in the string causes problems.
That's not an output issue. If you want to do set variable=stringvalue where stringvalue contains percent signs, you need to put two successive percent signs for each single percent sign you want in your stringvalue.

If you're reading your FOR pseudo-variable from an input file or pipe, percent signs are not special.

Last edited by flabdablet (18 Jul 2011 10:19)

----------------------------

#10 18 Jul 2011 11:09
flabdablet
jeb wrote:

It isn't broken, it's only a bit complex and undocumented.
The reason I claim it's broken is that the cmd parser (a) makes no distinction at all between literal quotes that occur in a line of script and quotes that result from parameter and variable expansion and (b) doesn't remove the literal quotes that delimit a string from the value so delimited and (c) provides no quoting mechanism that can suppress expansion of %variable% or !variable! constructs within a quoted string.

You can't just wrap quotes around any chunk of script text that ought to be interpreted purely as string data, because if variable or parameter expansions within that value end up inserting quotes, those will break the quoting you've wrapped around it and you will end up adding quotes to the outside of your string value that you may not necessarily want. That's broken parser design, in my book; there's simply no succinct way to say "I don't care what's in this string - just handle it as an opaque value".

The way the Bourne family of Unix shells handles quoted values (which is, admittedly, more complex) is far, far more convenient to use and does the Wrong Thing far, far less often.
jeb wrote:

I confirm that there isn't a safe way (with acceptable complexity) to pass variables to a subroutine.
That's exactly the kind of brokenness I'm complaining about.

In fact you can pass variables safely to subroutines - you just have to pass their names rather than their values. Effectively, you're writing subroutines with call-by-reference parameters.
jeb wrote:

The best way seems to be the DelayedExpansion-Toggling technic.
I'd be interested in seeing how you'd go about using that to fix my quickie :each subroutine so it does the right thing when passed parameter values containing embedded % and ! signs.

Cheers-
Stephen

----------------------------

#11 18 Jul 2011 13:03
jeb
flabdablet wrote:

The reason I claim it's broken is that the cmd parser (a) makes no distinction at all between literal quotes that occur in a line of script and quotes that result from parameter and variable expansion and (b) doesn't remove the literal quotes that delimit a string from the value so delimited and (c) provides no quoting mechanism that can suppress expansion of %variable% or !variable! constructs within a quoted string.
You can't just wrap quotes around any chunk of script text that ought to be interpreted purely as string data, because if variable or parameter expansions within that value end up inserting quotes, those will break the quoting you've wrapped around it and you will end up adding quotes to the outside of your string value that you may not necessarily want. That's broken parser design, in my book; there's simply no succinct way to say "I don't care what's in this string - just handle it as an opaque value".

You can't wrap quotes around percent variables,
but !variables! works always, as quotes and all other special characters are without any effect.

Code: Select all

@echo off
setlocal DisableDelayedExpansion
set "var1=complex &"^& ^> ^<"& < > !" !"
setlocal EnableDelayedExpansion
set "var2=!var1!"
echo var1 !var1!
echo var2 !var2!
set var
Output

Code: Select all

var1 complex &"& > <"& < > !" !
var2 complex &"& > <"& < > !" !
var1=complex &"& > <"& < > !" !
var2=complex &"& > <"& < > !" !
flabdablet wrote:

I'd be interested in seeing how you'd go about using that to fix my quickie :each subroutine so it does the right thing when passed parameter values containing embedded % and ! signs.
This should do the job

Code: Select all

@echo off
setlocal DisableDelayedExpansion    
set "params=aaa*;file*.*;file3.txt;a;b;c;"j k l m n o p";"quotes";Caret ^;Exclam ^!;Percent %%;Special &|<>"
setlocal EnableDelayedExpansion
SET LF=^


for %%L in ("!LF!") DO set "paramWithLF=!params:;=%%~L!"
for /F "delims=" %%a in ("!paramWithLF!") do (
    setlocal DisableDelayedExpansion    
    echo %%a
    endlocal
)
jeb

----------------------------

#12 18 Jul 2011 13:25
allal
Jeb wrote:

I confirm that there isn't a safe way (with acceptable complexity) to pass variables to a subroutine
there will never be
flabdablet wrote:

That's exactly the kind of brokenness I'm complaining about
you will always keep complaining
Jeb wrote:

The best way seems to be the DelayedExpansion-Toggling technic
if your string value contain !^% then it will die

because cmd is an old language all those problems are normal and because cmd developement was abondoned
those problem are in the source code and they will remain eternally and because human heart is so insistant and doesn't accept
Defeat,then it will urge you to automatically struggle and this time only for the void

working with percent sign in strings in cmd is not supported unless you want to have an unexpected result
open well you eyes cmd is not done for string manipulation

instead of correcting all this flaws in cmd or releasing update for this purpose, other newer language was born to do just that
and that can also help cmd better with built-in functions,properties and methods if called from cmd but can't help in cmd drawbacks

WE ARE IN 2011

what i have noticed in using other language that i'm having my output 100% guarranted,correct and faster but why not have the same result in cmd,because simply it something new,much more work and money were invested,more skilled programmed was involved

while in cmd i always keep struggling and fighting battles with the carret,percent sign,ampersand,exclamation mark,delayed expansion
and finally slowness,incorrect output,and sometimes writing uneeded warning comment "rem if string contain ampersand it will fail!!!"

please understand we are just cmd users not programmers that have the cmd source code and will modify it to make it support 2 billion length in single lines and arguments or to change the expansion rule to preserve characters or correct the escape character to make it work efficiently,normally as it created for in all case
in cmd there is no end to these problems and life is so short until you will surprised by your death and you didn't do what you are supposed to, where no other chance will be

----------------------------

#13 18 Jul 2011 14:39
flabdablet


jeb,

What characters could var1 contain to make set "var2=!var1!" succeed where set var2=!var1! fails?

allal,

Bourne shell is a considerably older language than cmd, was designed to do a comparable job on less powerful equipment, and although it certainly has its flaws and quirks it's clearly far better designed. The flaws in cmd reflect poor language design, not age. The fact that cmd is mostly backward compatible with the older command.com batch language from pre-NT versions of Windows is no excuse - Bourne shell is older than command.com, too.

But although cmd is deeply flawed in many ways, it's been my experience that invoking command-line tools via cmd scripts often allows me to do repetitive administrative tasks with much less code and much less research than manipulating Windows's ill-assorted collection of oddly-designed objects using jscript or (shudder) vbscript. That makes occasional exploration of cmd's dark corners a worthwhile use of time, as well as being an enjoyable puzzle-solving exercise in its own right.

A cmd script is glue that binds together the tools that actually do the work you're trying to get done. A good cmd script will spend most of its execution time inside those tools. If I find myself writing a cmd script that's mostly glue and not much tool, I will indeed reach for jscript instead.

I can see no point to PowerShell at all; near as I can tell, it's merely a crappier language than jscript for manipulating exactly the same underlying Windows objects you have available in wsh.

----------------------------

#14 18 Jul 2011 17:29
jeb
flabdablet wrote:

jeb,
What characters could var1 contain to make set "var2=!var1!" succeed where set var2=!var1! fails?
None.
But this quote-style guarantees, that no "invisible" spaces behind !var! are appended to the var2 content.
The complete content is set to var2 until the last quote, all characters behind the last quote are ignored
allal wrote:
Jeb wrote:
I confirm that there isn't a safe way (with acceptable complexity) to pass variables to a subroutine
there will never be
Sure, there is the REM-technic to access a %1 .. %n parameter independent of the content, even "&"&"& can be accessed.
allal wrote:
if your string value contain !^% then it will die
I tested it, it works as expected.

jeb

----------------------------

#15 18 Jul 2011 19:48
flabdablet


Jeb, could you possibly point me to an example of that REM technique?

----------------------------

#16 19 Jul 2011 07:11
jeb


Hi flabdablet,

This can handle nearly all possible parameters, like

myBatch.bat first second"&"^& hello^^

Code: Select all

@echo off
setlocal DisableDelayedExpansion
prompt X
(
  @echo on
  for %%b in (2) DO (
    REM #*# %*$
    REM #1# %1$
    REM #2# %2$
    REM #3# %3$
    REM
  )
  @echo off
) > params.txt

FOR /F "tokens=2,3* delims=#" %%P in (params.txt) do (
    set "paramName=%%P"
    set "param=%%Q"
    setlocal EnableDelayedExpansion
    set "param=!param:~1,-3!"
    echo !paramName!="!param!"
    endlocal
)
There is only one uncommon character left, which I can't handle currently

jeb

----------------------------

#17 19 Jul 2011 08:50
flabdablet


Jeb, that's completely twisted, evil, sick, wrong and nauseating. Well played!

----------------------------

#18 19 Jul 2011 09:36
flabdablet


I'm old and slow and still can't quite see why the second space and the $ sign are needed in REM #1# %1$ - does FOR perhaps fail to create %%Q if it sees emptiness past the second #?

Also, what is the uncommon character that doesn't get handled correctly?

----------------------------

#19 19 Jul 2011 10:50
jeb
flabdablet wrote:

I'm old and slow and still can't quite see why the second space and the $ sign are needed in REM #1# %1$ - does FOR perhaps fail to create %%Q if it sees emptiness past the second #?
It's that behind the REM is one harmless token, as if you try REM %1 - a simple "/?" in %1 breaks the code.
The space behind the # is only for the case, that the content of %1 begins also with one or more #, so it would be removed by the FOR delims.
The last character $ is necessary, too be safe against content with a caret at the end.
flabdablet wrote:

Also, what is the uncommon character that doesn't get handled correctly?
I remember now that there are two characters, and a possible third one could exists.
The CR (0x0D) and the LF(0x0A) and possible the SUB(0x1A=Ctrl-Z).

I suppose, it's impossible to see the CR, as all CR's are removed directly after the percent expansion and before entering the next parser phase.
Therefore it's removed before the REM is "executed".

But the more problematic character is the LF, as it can break out from the REM content.
Normally the REM statement is really strong. All behind the first token is completly ignored, even carets aren't "expanded" anymore.

But a LF inside of a parenthesis block (even in a percent variable), always starts a new valid and command line.

So a simple

Code: Select all

myBatch.bat myEvilPram<LF>echo hahahahaha<lf>goto :eof
Or try from the command line

Code: Select all

myBatch param^^^
More?
More? ^
More?
More? exit /b
Can break the REM-redirection technic.

jeb

Last edited by jeb (19 Jul 2011 10:53)

----------------------------

#20 19 Jul 2011 17:44
allal


well,finally jeb you decided to go to the prompt
it exist a way but they are all bad and time wasters
i don't call those methods simply a waste of time
what do you say if you use clipboard
1-iterate over the cmd file
2-set the current line in the clipboard
3-activate the cmd prompt window
4-get the clipboard and paste it into the prompt
5-send enter key stroke automatically
6-you cmd file need to be prepared when pasted not to cause a fatal error

like this example

@echo off

Code: Select all

for /F "tokens=*" %%G in (c:\script.cmd) do (
   nircmd win activate title "%systemroot%\system32\cmd.exe"
   nircmd clipboard set ~x22%%~G~x22
   nircmd ~$clipboard$ &rem unfortunately doesn't work
   nircmd sendkey enter press
)
sorry i don't have other alternative
this code show how idiot the cmd drive user to solve its problem
we will end in a mental hospital
oh i begin i begin my mind feel crazy
flabdablet wrote:

I can see no point to PowerShell at all; near as I can tell, it's merely a crappier language than jscript for manipulating exactly the same underlying Windows objects you have available in wsh.
you never used powershell before i swear
the main power of powershell reside in the pipe,this is what make it more powerful than any other scripting language
example :

# VERY POWERFUL PIPE
# THE USE OF THE PIPE IS THE POWERFUL AND ROBUST THAN ANY OTHER LANGUAGE
REPLACING TEXT FILES BEOMES NOT ONLY EAISER BUT ALSO FUN USING PIPES COOOOOOOOOL

> (cmd /c '@echo off &for /F "usebackq tokens=*" %G IN ("c:\file.txt") do echo %G'|out-string).replace("searchstr","replacestr")|set-content "c:\file.txt"

i assume you never used powershell before and jeb too,so i can tell about some feature you missed

PowerShell works with standard Windows commands and applications. You don’t
have to throw away what you already know and use.
• PowerShell introduces a powerful new type of command. PowerShell commands
(called cmdlets) share a common Verb-Noun syntax and offer many usability im-
provements over standard commands.
• PowerShell understands objects. Working directly with richly structured objects
makes working with (and combining) PowerShell commands immensely easier
than working in the plain-text world of traditional shells.
• PowerShell caters to administrators. Even with all its advances, PowerShell focuses
strongly on its use as an interactive shell: the experience of entering commands in
a running PowerShell application.
• PowerShell supports discovery. Using three simple commands, you can learn and
discover almost anything PowerShell has to offer.
• PowerShell enables ubiquitous scripting. With a fully fledged scripting language
that works directly from the command line, PowerShell lets you automate tasks
with ease.
• PowerShell bridges many technologies. By letting you work with .NET, COM,
WMI, XML, and Active Directory, PowerShell makes working with these previ-
ously isolated technologies easier than ever before.
• PowerShell simplifies management of data stores. Through its provider model,
PowerShell lets you manage data stores using the same techniques you already use
to manage files and folders.

powershell gathers all scripting language in one and more.


#WORKING WITH COM OBJECT BECOME EASIER THAN EVER NOT NEED TO SPECIFY THE WHOLE THING

Code: Select all

$colItems = get-wmiobject -class "Win32_Process"
foreach ($objItem in $colItems) {
      write-host $objItem.Name, $objItem.WorkingSetSize
}
#NOT ONLY POWERSHELL CONNECT TO COM OBJECT BUT ALSO TO A HUGE COLLECTIO OF THE NEW .NET FRAMEWORK CLASSES
here are a little i picked
System.DateTime Represents an instant in time, typically expressed as a date and time of day.
System.Guid Represents a globally unique identifier (GUID).
System.Math Provides constants and static methods for trigonometric, logarithmic, and other common mathematical functions.
System.Random Represents a pseudorandom number generator, a device that produces asequence of numbers that meet certain statistical

requirements forrandomness.
System.Convert Converts a base data type to another base data type.
System.Environment Provides information about, and means to manipulate, the current environment and platform.
System.Console Represents the standard input, output, and error streams for consoleapplications.
System.Text.RegularExpressions.Regex Represents an immutable regular expression.
System.Diagnostics.Debug Provides a set of methods and properties that help debug your code.
System.Diagnostics.EventLog Provides interaction with Windows event logs.
System.Diagnostics.Process Provides access to local and remote processes and enables you to start andstop local system processes.
System.Diagnostics.Stopwatch Provides a set of methods and properties that you can use to accuratelymeasure elapsed time.
System.Media.SoundPlayer Controls playback of a sound from a .wav file.
Microsoft.Win32.Registry Provides RegistryKey objects that represent the root keys in the localand remote Windows registry and static methods to access key/value pairs.
Microsoft.Win32.RegistryKey Represents a key-level node in the Windows registry.

#SUPPORT EVENT FROM .NET AND WMI here are some
System.AppDomain AssemblyLoad
System.AppDomain TypeResolve
System.AppDomain ResourceResolve
System.AppDomain AssemblyResolve
System.AppDomain ReflectionOnlyAssemblyResolve
System.AppDomain UnhandledException
System.Console CancelKeyPress
Microsoft.Win32.SystemEvents DisplaySettingsChanging
Microsoft.Win32.SystemEvents DisplaySettingsChanged
Microsoft.Win32.SystemEvents installedFontsChanged
Microsoft.Win32.SystemEvents LowMemory
System.Net.WebClient OpenReadCompleted
System.Net.WebClient OpenWriteCompleted
System.Net.WebClient DownloadStringCompleted
System.Net.WebClient DownloadDataCompleted
System.Net.WebClient DownloadFileCompleted
System.Net.WebClient UploadStringCompleted
System.Net.WebClient UploadDataCompleted
System.Net.WebClient UploadFileCompleted
System.Net.WebClient UploadValuesCompleted
System.Net.WebClient DownloadProgressChanged
filesystemwatcher created,modified,deleted,renamed

#correct working escape char

Code: Select all

$var=string
#expand var $var
#don't expand `$var

# USE REGULAR EXPRESSION NOT ONLY FOR CHECKING AND SEARCHING BUT ALSO REPLACING,SPLITTING STRINGS

Code: Select all

#how can you check for valid ip or email with cmd
#CHECK
> echo "name@hotmail.com"| select-string "\b[A-Z0-9._%%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b"

#REPLACE
> $a=[regex]::replace("c:\!p%a%th\|\\**\\\script\ps\\\\\!","!|\||\*|%","");$a=[regex]::replace($a,"\\\\+","\")
> c:\path\script\ps\

#SPLIT
> [regex]::split("c:\*\\\sc|ri|pt\p///s\\%%%\\\!","!|\||\*|%|/|\\\\+")|join-string
> c:\path\script\ps\

#GET any command output only by assaining the command to a var and not using a whole for loop

$a=cmd /c dir /b /s c:\

#USE INFINITE STRING MANIPULATION IN ONE GO WITH POWERSHELL IN ONE COMMAND

Code: Select all

(((((" Hello there world".trimstart().replace("there world","poison character&&|%!!^").Split().length)*100).tostring().indexof("0")+3|`
foreach {[math]::sqrt($_)/1kb}|out-string).remove(1)|get-member| where`
 {$_.name -eq "lastindexof"}).name.gettype().name.toupper().insert(0,"c:\s[]cr\\i***pt\\\<>\a{ll(al)}\")|`
foreach {[regex]::split($_,"\\\\+|\[|\]|\*|<|>|\{|\}|\(|\)")}|join-string).Tolower()|`
foreach {test-path $_}|write-host -foreground red -background yellow
what the...what is this code was doing???
1- fist remove the leadine space --> "Hello there world"
2- replaces "there world" by "poison character&&|%!!^" --> "Hello poison character&&|%!!^"
3- split the whole string which results in array of three entries
hello
poison
character&&|%!!^
4-get the length of this array --> 3
5-multiply the length result 3 * 100
6-converts the result 300 to string so we will be able to use string prperties and methods on it --> "300"
7-getthe index of 0 in the string "300" and add 3 to result --> 4
8-get the square root of 4 and divide it by the constant 1 kilobytes --> 0.001953125
9-change int object to string and truncate the result --> 0
10-show type of the current object --> string
11-convert the current object name to uppercase --> STRING
12-insert incorrect path at the first index --> "c:\s[]cr\\i***pt\\\<>\a{ll(al)}\STRING"
13-delete any illegal character or extra by splitting them with regular expression ---> c:\script\allal\STRING
14-convert the whole path string to lowercase ---> c:\script\allal\string
15-test the path if it exist and write the final output in red with a yellow background color ---> False
16- please please stop...this has no end!!!

NOTE: YOU NEED NO LESS THAN 1000 LINE OF CODE AND YOU NEED TO BE EXPERT IN ORDER TO DO IT WITH CMD WHERE AS ALIKE CODE IN POWERSHELL IS JUST

A CHILD PLAY
AND WITH CMD YOU MAY FAIL



#EVERYTHING YOU WORK WITH IS KNOWN BY POWERSHELL,IS IT A HUMAN???
command is a command
Alias is an alias
function is function
application is an application

Command
resolve-path c:\wi*\system[0-9]*\shell[0-9][0-9].*
function
e,g get-FullPath archive.7z,archive.rar -skip c:\,d:\ -showfirst
application
xcopy /S /i source destination
ALL CAN BE CALLED DIRECTLY by their names as they are the same thing but function is function object,cmdlet is a cmdlet object ...

in other language you will always say where is my function and what is its correct name,yes human forget but powershell "don't"
you will always get confused,sometimes i found a function very hard, and when you need it,it is never there
in powershell everything is known and you will not get lost with the profile script and all buit in cmdlet are ready to help
Get-command will tell you if it is a command,alias,function and exacly what is it so everything is known and use wilcard to find its correct name

# CONVERT APPLICATION TO POWERSHELL COMMAND USING A FUNCTION
e,g
xcopy-items -path d:\ -destination c:\ -force
which is the equivalent of
xcopy /H/R/C/Y/I/O/X/G d:\ c:\

you create the function yourself ok

#CREATES GUI NOT IMPORTANT FOR ADMIN

#AND THE BIG SURPRISE
BRING ALL THE POWER OF POWERSHELL COMMAND,FUNCTIONS,ALIAS,OBJECT,METHOD,PROPERTIES TO CMD DIRECTLY WITHOUT CREATING A TEMP FILE

Code: Select all

@echo off &setlocal
REM get available fixed and removable drives
set "Customfunction=powershell.exe -nologo Get-Drives"
set "Argument=-Fixed -Removable"
for /f "tokens=*" %%G IN ('%Customfunction% """%Argument%"""') do echo %%G
REM OUTPUT ---> c:\ d:\ e:\ h:\

REM get computer name with the net.exe application
for /F "tokens=*" %%G In ('powershell -nologo ^(net user^^^|select-string """\\\\"""^^^|out-string^).split(""" """^)^^^|select-object -last 1^^^|foreach ^{$_.replace("""\\"""^,""""""^)^}') do endlocal&if not [%1]==[] ( call set "%~1=%%G"&exit/b) else echo %%G&exit/b
REM OUTPUT ---> ALLAL_PC

Code: Select all

@echo off &setlocal
REM GET THE POWERSHELL POWER IN CMD 
set "ps=powershell.exe -nologo"
for /f "tokens=*" %%G IN ('%ps% write-host -nonewline """>>>printing string length is: """^;"""string""".length^;"""-"""*100^;write-host-nonewline """>>>printing directory content: """^;get-childitem^;"""`n`n"""^;"""-"""*100^;write-host -nonewline """>>>printing date info: """^;get-date^;"""-"""*100^;$str^="""some day......scripting guru""" ^;"""`n"""^;write-host -nonewline """>>>printing first found dot index in the string $str is: """ ^;$str.indexof^("""."""^)^;"""-"""*100^;""">>>get regional setting"""^;get-culture^;"""-"""*100^;""">>>from commands display only functions :"""^;get-command^^^|where{$_.commandtype ^-eq """function"""^}^^^|foreach {$_.name}^;"""-"""*100^;""">>>display process name starting by s:""" ^;get-process^^^|where{$_.name -like """s*"""}^^^|select-object name^;"""-"""*100^;""">>>display running service"""^;get-service^^^|where{$_.status -like """run*"""}^^^|select-object DisplayName^;"""-"""*100^;""">>>choose a random number between minimum and maximum"""^;get-random -min 100 -max 200^;"""-"""*100^;""">>>reverse case of STRing with custom function reverse-case"""^;reverse-case """STRing"""^;""">>>display c:\file.txt content"""^; Get-Content c:\file.txt^') do echo %%G
OUTPUT

Code: Select all

>>>printing string length is: 6
----------------------------------------------------------------------------------------------------
>>>printing directory content:
Directory: Microsoft.PowerShell.Core\FileSystem::E:\Program Files\Notepad++
Mode           LastWriteTime       Length Name
----           -------------       ------ ----
d----     4/13/2011 10:55 AM        <DIR> $INSTDIR
d----     4/13/2011 10:55 AM        <DIR> $PLUGINSDIR
d----     4/13/2011 10:55 AM        <DIR> $TEMP
d----     4/13/2011 10:55 AM        <DIR> $[37]
d----     4/13/2011 10:55 AM        <DIR> localization
d----     5/23/2011 11:50 PM        <DIR> plugins
d----     4/13/2011 10:55 AM        <DIR> themes
d----     4/13/2011 10:55 AM        <DIR> updater
d----     5/23/2011 11:50 PM        <DIR> user.manual
-a---     6/13/2011  2:58 PM           15 Absent
-a---     6/10/2011 10:50 AM           12 allal
-a---     6/11/2011 11:41 AM           12 belgiumcode.cmd
-a---     3/30/2011 12:27 AM          913 change.log
-a---      2/9/2011 12:56 AM         4539 config.model.xml
-a---     5/23/2011 11:48 PM         7257 config.xml
-a---      7/1/2011 12:56 PM          108 dateadd.vbs
-a---     6/17/2011  2:17 PM            0 english
-a---     6/18/2011  4:21 PM            0 findstr
-a---     6/17/2011  2:17 PM            0 french
-a---     6/13/2011  5:28 PM          157 getregval.js
-a---     5/23/2011 11:48 PM          109 insertExt.ini
-a---     6/11/2011  5:00 PM          118 key.tmp
-a---      2/9/2011 12:56 AM        91509 langs.model.xml
-a---      4/1/2011 11:36 AM        92130 langs.xml
-a---      2/9/2011 12:56 AM        14971 license.txt
-a---     6/17/2011 10:01 PM            0 notepad++.e
-a---     5/23/2011 11:50 PM      1523712 notepad++.exe
-a---     9/29/2010  2:25 AM         7406 npp.ico
-a---      5/5/2010  9:38 PM         6656 nppIExplorerShell.exe
-a---      2/9/2011 12:56 AM       296448 NppShell_04.dll
-a---      6/9/2011 10:09 AM           16 out.tmp
-a---      7/2/2011  5:32 PM         7452 PSerror.txt
-a---      2/9/2011 12:56 AM         1543 readme.txt
-a---     3/21/2011 10:44 PM       622592 SciLexer.dll
-a---      2/9/2011  9:00 PM         1864 session.xml
-a---     5/23/2011 11:48 PM         3976 shortcuts.xml
-a---      2/9/2011 12:56 AM        95613 stylers.model.xml
-a---     5/15/2011  8:32 PM        99028 stylers.xml
-a---     6/24/2011 10:41 AM           48 temp
-a---     6/17/2011  2:18 PM           99 tempkey.txt
-a---     5/23/2011 11:50 PM       249188 uninstall.exe
----------------------------------------------------------------------------------------------------
>>>printing date info:
DisplayHint : DateTime
Date        : 7/19/2011 12:00:00 AM
Day         : 19
DayOfWeek   : Tuesday
DayOfYear   : 200
Hour        : 12
Kind        : Local
Millisecond : 640
Minute      : 13
Month       : 7
Second      : 8
Ticks       : 634466743886406250
TimeOfDay   : 12:13:08.6406250
Year        : 2011
DateTime    : Tuesday, July 19, 2011 12:13:08 PM
----------------------------------------------------------------------------------------------------
>>>printing first found dot index in the string some day......scripting guru is: 8
----------------------------------------------------------------------------------------------------
>>>get regional setting
Parent                         : en
LCID                           : 1033
KeyboardLayoutId               : 1033
Name                           : en-US
IetfLanguageTag                : en-US
DisplayName                    : English (United States)
NativeName                     : English (United States)
EnglishName                    : English (United States)
TwoLetterISOLanguageName       : en
ThreeLetterISOLanguageName     : eng
ThreeLetterWindowsLanguageName : ENU
CompareInfo                    : CompareInfo - 1033
TextInfo                       : TextInfo - 1033
IsNeutralCulture               : False
CultureTypes                   : SpecificCultures, InstalledWin32Cultures, FrameworkCultures
NumberFormat                   : System.Globalization.NumberFormatInfo
DateTimeFormat                 : System.Globalization.DateTimeFormatInfo
Calendar                       : System.Globalization.GregorianCalendar
OptionalCalendars              : {System.Globalization.GregorianCalendar, System.Globalization.GregorianCa
UseUserOverride                : True
IsReadOnly                     : False
----------------------------------------------------------------------------------------------------
>>>from commands display only functions :
A:
Add-DirectoryLength
Add-ShortPath
B:
C:
c_nameconvert
cd..
cd\
clean-pathunworking
Clear-Host
D:
Disable-PSRemoting
Dismount-VHD
do-events
E:
Edit-File
Edit-HostProfile
Edit-Profile
Enable-OpenPowerShellHere
extract
F:
G:
Get-drives
Get-emptydir
Get-full
Get-Help
get-OpenLockers
Get-ParentPrefix
Get-ScreenCss
Get-ScreenHtml
Get-Verb
Get-ViewDefinition
H:
help
I:
ImportSystemModules
Invoke-BatchFile
Invoke-Elevated
Invoke-GC
Invoke-Method
Invoke-Reflector
J:
K:
L:
less
M:
man
mkdir
more
Mount-VHD
move-smart
N:
O:
Out-Speech
P:
prompt
Q:
QuoteList
QuoteString
R:
randomColor
Resolve-ErrorRecord
Resolve-HResult
Resolve-WindowsError
reverse-case
S:
Set-LocationEx
Set-ReadOnly
Set-Writable
Show-Tree
silentmsi
split-more
Stop-RemoteProcess
T:
TabExpansion
test-space
Tweak-path
U:
Update-backup
V:
W:
write-caution
X:
xcopy-items
Y:
Z:
----------------------------------------------------------------------------------------------------
>>>display process name starting by s:
Name : services
Name : SmartDefrag
Name : smss
Name : spoolsv
Name : svchost
Name : svchost
Name : svchost
Name : svchost
Name : svchost
Name : System
----------------------------------------------------------------------------------------------------
>>>display running service
DisplayName : Application Layer Gateway Service
DisplayName : Ati HotKey Poller
DisplayName : Windows Audio
DisplayName : Cryptographic Services
DisplayName : DCOM Server Process Launcher
DisplayName : DHCP Client
DisplayName : Logical Disk Manager
DisplayName : DNS Client
DisplayName : ESET Service
DisplayName : Error Reporting Service
DisplayName : Event Log
DisplayName : COM+ Event System
DisplayName : Fast User Switching Compatibility
DisplayName : Help and Support
DisplayName : Java Quick Starter
DisplayName : Server
DisplayName : Workstation
DisplayName : TCP/IP NetBIOS Helper
DisplayName : Network Connections
DisplayName : Network Location Awareness (NLA)
DisplayName : Plug and Play
DisplayName : IPSEC Services
DisplayName : Protected Storage
DisplayName : Remote Access Connection Manager
DisplayName : Remote Registry
DisplayName : Remote Procedure Call (RPC)
DisplayName : Security Accounts Manager
DisplayName : Task Scheduler
DisplayName : Secondary Logon
DisplayName : System Event Notification
DisplayName : Windows Firewall/Internet Connection Sharing (ICS)
DisplayName : Shell Hardware Detection
DisplayName : Print Spooler
DisplayName : System Restore Service
DisplayName : SSDP Discovery Service
DisplayName : Telephony
DisplayName : Terminal Services
DisplayName : Themes
DisplayName : Distributed Link Tracking Client
DisplayName : Windows Time
DisplayName : WebClient
DisplayName : Windows Management Instrumentation
DisplayName : Security Center
DisplayName : Automatic Updates
DisplayName : Wireless Zero Configuration
----------------------------------------------------------------------------------------------------
>>>choose a random number between 100 and 200
105
----------------------------------------------------------------------------------------------------
>>>reverse case of STRing with custom function reverse-case
strING
----------------------------------------------------------------------------------------------------
>>>display c:\file.txt content
cmd:thanks powershell for strengthening me with this unbelievable power
HOPE THIS TIME YOU WILL TRY POWERSHELL
BYE OBSTINATE TIME WASTERS

Last edited by allal (19 Jul 2011 20:19)

----------------------------

#21 20 Jul 2011 02:38
flabdablet

Allal,

I can see you're excited about PowerShell.

I am less so, simply because I came to Windows scripting via Unix scripting. Unix has always had a properly expressive and reasonably tidy shell, compared to which cmd has always looked like a noddy toy. PowerShell strikes me as yet another instance of Microsoft re-inventing a wheel, covering it in bling, and promoting it as something that at last! allows us to roll! instead of dragging! when the entire non-Microsoft universe has already been rolling for decades.

I'm also not particularly in love with PowerShell's object pipelines. Pipelines as such are indeed a wonderful thing, and the ability they give you to glue simple operations together to form complex ones is indeed very useful. But PowerShell's object pipes require me to consult an object model reference every time I use them, and I find that very irritating. If I'm going to go to the trouble of consulting object documentation, I'm no longer really concerned with the number of lines of code it takes to do something, because the amount of time I spend typing lines of code is dwarfed by the amount of time I spend ploughing through the documentation. Text pipelines work just fine; I think I've wished for the ability to pipe something more structured maybe two or three times in thirty years of shell programming.

PowerShell's ability to use the same syntax for invoking an internal alias, an internal function and an external command is not new. Bourne shell has had the same ability since before the release of DOS.

PowerShell, much like like perl before it, is a great mishmash of borrowed concepts onto which every script author will impose their own preferred set of self-imposed limitations. Like perl, that makes it a really good tool for generating write-only code.

I could go on. But this is the cmd forum, not the PowerShell forum, and if it's all the same to you I'd rather get back to playing with noddy toys for fun.

----------------------------

#22 20 Jul 2011 03:10
flabdablet
jeb wrote:

It's that behind the REM is one harmless token, as if you try REM %1 - a simple "/?" in %1 breaks the code.
Oh, that's priceless! I knew REM was actually a command, but it had never occurred to me that it ever actually did something :-)
jeb wrote:

The space behind the # is only for the case, that the content of %1 begins also with one or more #, so it would be removed by the FOR delims. The last character $ is necessary, too be safe against content with a caret at the end.
Fair enough. But why set "param=!param:~1,-3!" rather than set param=!param:~1,-2! - given the safety of !expansion! I can see no need for the quoted set, and given that you're trying to strip only one leading space and one trailing $, why -3 rather than -2?

Edit: never mind. It's because params.txt ends up with trailing spaces on the end of each line because of the weird way FOR echoes its controlled command when ECHO is on. And this is also the reason for the blank REM at the end of the tower of REMs - the last command in the bunch that FOR echoes gets one less trailing space, and without the blank REM, this messes up the substring selection.

Jeb, this thing is a tour de force. It is without a doubt the nastiest, ugliest, most brutal cmd hack I have ever encountered, and it deserves a place in every cmd programmer's toolkit. You deserve some sort of medal :-)

Last edited by flabdablet (20 Jul 2011 17:10)

----------------------------

#23 20 Jul 2011 17:55
flabdablet


Here's what I've got after playing with the technique for a while. The main deficiency in jeb's original is the difficulty in getting to the actual parameter values once they're captured, as the variables that hold them only exist inside a setlocal/endlocal block inside a FOR loop.

Code: Select all

@set echo=off
@echo %echo%
setlocal disabledelayedexpansion
set args=%temp%\args.%random%.%random%.txt
prompt X
(
  @echo on
  for %%A in (1) do (
    rem #0# %*$
    rem #1# %1$
    rem #2# %2$
    rem #3# %3$
    rem #4# %4$
    rem #5# %5$
    rem #6# %6$
    rem #7# %7$
    rem #8# %8$
    rem #9# %9$
    rem
  )
  @echo %echo%
) >%args%

for /f "tokens=2,* delims=#" %%A in (%args%) do set %%A=%%B
del %args%

setlocal enabledelayedexpansion
for /L %%A in (0,1,9) do set %%A=!%%A:~1,-3!

rem script from this point on can use !1!, !2!, !3! etc to insert args

for /L %%A in (0,1,9) do (
  if defined %%A echo %%A=!%%A!
)

endlocal
endlocal
----------------------------

#24 21 Jul 2011 14:02
jeb


@allal:
powershell is only another tool of microsoft, even it is powerfull, it only works on a windows plattform for the next few years, before they decide to replace it with a new more powerfull "gigashell" or whatever.

cmd is fun for me, I didn't want to write "real world" solution with it.
But it's nice to search for solutions for nearly impossible tasks in batch.
flabdablet wrote:

Jeb, this thing is a tour de force. It is without a doubt the nastiest, ugliest, most brutal cmd hack I have ever encountered, and it deserves a place in every cmd programmer's toolkit. You deserve some sort of medal :-)
Thanks, that's the cause I love cmd.exe, it's so poor programmed that even a simple task needs really hard coding.

Btw. There are more nasty cmd hacks, I created.
One of my current projects is a stackDumper for batch written in batch :-)
And yes ... it is possible

Code: Select all

@echo off
....
call :func1
..
:func1
call :nested
...

:nested
if err==1 call :stackDump

Should output

func1 / called from line 10
  nested / called from line 26
    stackDump  / called from line 44
jeb
Post Reply