Thursday 31 July 2008

Using help to help yourself (part 2): publishing batch help information in HTML format

Well, it took quite a bit of head-scratching but here it is: a batch script that outputs information about commands in HTML format.

This is the code (NOTE: works with french accented words)

[commands_site.bat]

@echo off

:init
setlocal enabledelayedexpansion
set out_dir=site
set page_sub=pages
set page_dir=%out_dir%\%page_sub%
if not exist %page_dir% mkdir %page_dir%
goto create_site

:create_site
set ifile=%out_dir%\index.html
> %ifile% echo ^<html^>^<head^>^<title^>Commands index^</title^>^</head^>
>> %ifile% echo ^<body^>
for /F "tokens=1" %%C in ('help') do (
call :set_is_command %%C
if "!is_command!"=="1" (
echo Handling: %%C
set cfile=%page_dir%\%%C.html
>> %ifile% echo ^<a href="%page_sub%\%%C.html"^>%%C^</a^>^<br/^>
:: set cfile=CON
> !cfile! echo ^<html^>^<head^>^<title^>%%C^</title^>^</head^>
>> !cfile! echo ^<body^>^<h2^>%%C^</h2^>^<pre^>
for /F "delims=" %%T in ('help %%C') do (
set str=%%T
set str=!str:…=^&agrave;!
set str=!str:‚=^&eacute;!
set str=!str:Š=^&egrave;!
set str=!str:ˆ=^&ecirc;!
set str=!str:‰=^&euml;!
set str=!str:Œ=^&icirc;!
set str=!str:‹=^&iuml;!
set str=!str:“=^&ocirc;!
set str=!str:—=^&ugrave;!
set str=!str:–=^&ucirc;!
set str=!str:‡=^&ccedil;!
set str=!str:ÿ=^&nbsp;!
>> !cfile! echo !str!
)
>> !cfile! echo ^<br/^>^<br/^>
>> !cfile! echo ^<a href="../index.html"^>Back to index/Retour ^&agrave; l'index^</a^>
>> !cfile! echo ^</pre^>^</body^>^</html^>
)
)
>> %ifile% echo ^</body^>
>> %ifile% echo ^</html^>

goto end

:set_is_command
set name=%~1
set is_command=1
if not "%name%"=="" (
set num=1
for /F "usebackq tokens=1 delims=ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%W IN ('%name%') do (
set num=0
)
set is_command=!num!
)
goto blackhole

:end
echo Press any key to quit...
pause > NUL

:blackhole

So, how does it work?

One
We enable delayedexpansion. This allows us to dynamically set variables in FOR loops.

Two
We prepare the output directories (mkdir). The root of the "site" is the site directory (this is where the site index will get stored). In this directory, a subdirectory is created which will hold all the pages (one for each command): the pages subdirectory.

Three
A loop (for /F "tokens=1" %%C in ('help')...) is used to loop through all the lines output by the help command. Each command is output starting with the command name and one or more lines of short explanations like the following example shows:

VERIFY Indique à Windows 2000 s'il doit ou non vérifier que les fichiers
sont écrits correctement sur un disque donné.

Notice the accented characters shown in the explanation (é, à).

Four
Obviously we only want to retrieve the command names (e.g. VERIFY) and nothing else. To do this we must check the first token of every line. In our case the first token will be VERIFY for the first line, and "sont" for the second line. Only the first of these two tokens is an actual command name. Fortunately, it has only uppercase letters.
The set_is_command subroutine makes sure the is_command variable is set to 1 if the token is a command (i.e. all uppercase letters) or 0 if the token isn't (one or more lowercase letters e.g. "sont").

Five
The script will output: one file for each command (containing its detailed help information) and an index file which will reference all these command pages.
For every command name, we:
- create a link in the index file
- create a file containing the detailed information (the result of help %commandname%)

Six
Notice there is a strange section with a few lines like:
set str=!str:Œ=^&icirc;!

At first, when I tried to output the result of 'help %commandname%' to an HTML file, the accented characters got replaced by different characters. For instance: "é" was shown as ",", "è" was shown as "Š", and so on and so forth. After some Googling and much head-scratching, I came up with this.
The idea is to replace the "bad" character with a character which will give me the desired result. Because I am working with HTML a good way to do this is to replace these accented characters with the corresponding HTML entities. Thus, é becomes &eacute;, à becomes &agrave;, etc.
I used a simple replacement syntax set str=!str:S=R! where S represents what you're searching for and R represents the desired replacement. Neat little trick.

There is a catch however. To work properly with accented characters, you need to open the batch file using EDIT (cmd > EDIT). If you open the above code using EDIT you will find that "…" becomes "à", "‚" becomes "é", "Š" becomes "è", etc. Once you have finished entering the accented characters, you can then revert to notepad for instance but the characters will look "strange" (i.e. as in the example above).
I guess you could do exactly the same with text, by typing the accented characters in notepad (for instance), then opening the file in EDIT. The notepad characters will look weird in EDIT but you can then type in EDIT the original characters to be replaced with the "weird" notepad characters using the S=R syntax. I haven't tried this but I expect it works.

Well, I think that's it. I hope someone will find this useful!

Thoughts?

Wednesday 30 July 2008

Batch programming: using help to help yourself

Nothing I know of can quite beat the Linux/Unix "man" pages but here's a quickie on how to use the help command from the Windows command prompt.

Step 1: start the prompt (Start -> Run -> (type) cmd -> Enter)

Step 2: type help

cmd> help

This displays a list of available batch commands.

Step 3: get help on command of your choice (e.g. "FOR")

cmd> help for


Reading all of this in black and grey is pretty tedious, so I have started on a script that will output all these command in HTML format. Run it once and it will create a folder containing:
- an link index to all the commands
- one page per command with the relevant details

I currently have two major problems with this:
1. Trailing "spaces": I can't seem to remove trailing spaces successfully (not even sure they really are spaces)
[EDIT: PROBLEM 1 SOLVED, shall post code tomorrow]
2. Accented characters: I am using French, and accented characters are output as anything but what they should be. For instance "é" is output ",", etc. and I have yet to find a full-DOS solution to this problem.
[EDIT: PROBLEM 2 SOLVED, shall post code tomorrow]

Any suggestions more than welcome regarding these two issues =)

Tuesday 29 July 2008

Batch programming tip#15: Getting file information

This example speaks for itself I think. You can obviously also use it in FOR loops or subroutines. It show how to retrieve lots of useful information about files (in this exemple the first argument).

[info.bat]

@echo off

:init_vars
if [%1]==[] goto what_file
if not exist %1 goto what_file
goto show_info

:show_info
echo.
echo General information
echo -------------------
echo Fully qualified name (%%~f1): %~f1
echo Drive letter (%%~d1): %~d1
echo Path (%%~p1): %~p1
echo File name (%%~n1): %~n1
echo File extension (%%~x1): %~x1
echo Date time (%%~t1): %~t1
echo Size (%%~z1): %~z1
echo File attributes (%%~a1): %~a1
goto show_combinations

:show_combinations
echo.
echo Some possible combinations
echo --------------------------
echo Drive and path (%%~dp1): %~dp1
echo Filename and extension (%%~nx1): %~nx1
echo Path using short names (%%~fs1) : %~fs1
echo.
goto eof

:what_file
echo Please provide valid file.
goto eof

:eof
echo Press any key to quit
pause > NUL


Simply call it using something like:

[info_call.bat]

@echo off
call info test_file_info.longext


These allow you to get: file size, date time, etc. Really useful stuff =D.

Have fun!

Monday 28 July 2008

Cuil - Search Engine

It seems to have been a long long while since any new search engine has actually surfaced on the web and made Google look anything different to Goliath (OK, I know that's a bad example because Goliath lost and Google just keeps winning :-)).

But look out for this new rising star: http://www.cuil.com/

Co-founded by ex-Google employees, Cuil has already crawled more pages than the Search Engine Giant itself! With a name from the Gaelic word for Knowledge, it looks like you may not be able to ignore this site for too long!

Among some of its really neat features are:
- two or three-column presentation of search results
- context-driven results with a drilldown feature which allows you to easily get to other pages in the same context by using an "Explore by category" link box located at the right-hand side of the screen (for instance, try typing "e-learning technologies")
- search tabs: in some cases search tabs will appear at the top(-ish) of the page with "sub-searches" (for instance, try searching for "insects" and you will get tabs relating to "Flying insects", "Beneficial insects", "Harmful insects" and many more)

Add to that an excellent FAQ, clear an meaningful explanations, cool web design, plus lots of things I probably missed, and you must be on to a winner!

This afternoon (by GMT+1 standards), they were already adding capacity, with their search page sporting the message:

We’ll be back soon...
Due to overwhelming interest, our Cuil servers are running a bit hot right now. The search engine is momentarily unavailable as we add more capacity.
Thanks for your patience.

It's a hit! =D

What do you think? Can Cuil unsettle Google on the search engine market?

Sunday 27 July 2008

Batch programming tip#14: The difference between :: and REM

Both REM and :: are commonly used to "comment out" a line in batch files, so what's the difference between them?

REM is the true "Remark" command. In other words it is treated as such and interpreted.

::, on the other hand, is an invalid label (a label starts with a colon) and is therefore simply skipped.

What this means is using REM is slower than using :: because :: means the line is skipped and the next is interpreted whereas with REM the line isn't skipped in the first place.

Thoughts?

Friday 25 July 2008

Batch programming tip#13: Using setlocal enabledelayedexpansion

Delayed expansion is pretty tricky to explain. It basically means you are making sure that your variable is evaluated as many times as necessary and not just once (as would normally be the case).

The typical use for this is when using a "for" command. Without delayed expansion, variables do not appear to get set correctly. Why? Because they are evaluated once for the for command (rather than each time you loop) which results in apparently strange behaviour.

Example:

@echo off

:action
set num=0
for /l %%N IN (1,1,9) do (
echo %num%
set /a num=%num%+1
)
goto show_result

:show_result
echo Num is actually now worth: %num%
goto eof

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

The for /l %%N IN (1,1,9) do command basically creates a loop from 1 to 9 with a step of 1 (so nine passes).
Anyhow, anyone would go crazy trying to debug this thing: it outputs nine zeros and a total worth of 1!

Enter delayed expansion however and things get back to normal:

@echo off

:init_sys
setlocal enabledelayedexpansion

:action
set num=0
for /l %%N IN (1,1,9) do (
echo !num!
set /a num=!num!+1

)
goto show_result

:show_result
echo Num is actually now worth: %num%
goto eof

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

Notice we use the exclamation mark instead of % to reference variables within the for loop. This makes sure the variable is reassessed every time we use it.

I have written a short example below with a loop inside a loop. It loops through a sentence and shows every word separately using a call to an appropriate subroutine.


@echo off

:init_sys
setlocal enabledelayedexpansion

:init_vars
set text=The quick brown fox jumps over the lazy dog

:action
echo Displaying text using %%: %text%
echo Displaying text using ^^!: !text!

for /l %%N IN (1,1,9) do (
call :get_substr %%N "%text%"
echo Token: !strtok!
)
goto eof

:get_substr
set token=%~1
set string=%~2

for /F "usebackq tokens=%token% delims= " %%w in ('!string!') do (
set strtok=%%w
)
goto blackhole

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

Note that if you don't use the delayed expansion properly (e.g. in the second for loop: '!string!') all hell will break loose... I know because I tried :D

The second use of delayed expansion is to nest variables like so:

@echo off

:init_sys
setlocal enabledelayedexpansion

:init_vars
set text=The quick brown fox jumps over the lazy dog

:action
for /l %%N IN (1,1,9) do (
call :getchars %%N
)
goto eof

:getchars
set num=%~1
echo !text:~0,%num%!
goto blackhole

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

What this script does is successively retrieves N (N being 1 to 9) number of characters from our sentence "The quick brown fox jumps over the lazy dog".
To do this we nest the %num% variable in our "substring" notation:
!text:~0,%num%!

Cool.

Thoughts?

Sunday 20 July 2008

Batch programming tip#12: Creating a timestamp

Now we can substring, creating a timestamp is really easy.

This is one simple way of doing this using the %date% and %time% system variables to create timestamped files.


@echo off

:create_file
call :get_timestamp
type NUL > %timestamp%.file
goto eof

:get_timestamp
set d_stamp=%date:~11%%date:~8,2%%date:~5,2%
set t_stamp=%time:~0,2%%time:~3,2%%time:~6,2%%time:~9%
set timestamp=%d_stamp%%t_stamp%
goto blackhole

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

(We reverse year, month and day so that the files are naturally sorted in the 'right' order.)

The create_file section retrieves the timestamp (e.g. 2008071719410698) created by the get_timestamp subroutine and uses it to create an empty file. Obviously this can have multiple uses like timestamping log information for instance.

(Note: day and month probably appear in a different order according to sytem locale.)

Thoughts?

Saturday 19 July 2008

Batch programming tip#11: Using The Substring Equivalent

As you know, most (all?) programming languages provide a substring() method of some sort which allows you to retrieve part of a string variable.

To do this in batch you can use the following syntax:
%var:~start% or
%var:~start,length%
where start is the index of the first character to retrieve (the first character in a string is indexed 0) and length is the length of the substring to retrieve. If no length is given the whole remaining string is shown.

In this example, we use a system variable %date% which holds the current system date and then echo the current system month and year.

@echo off

:get_year
echo System date: %date%
echo System month: %date:~8,2%
echo System year: %date:~11%
goto eof

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole


You can also use this method 'backwards'. Assume we didn't know the length of the %date% variable string, and wanted to retrieve the four last characters which represent the year.
We could then use the following syntax: %date:~-4% with a minus preceding the 4. This moves us back 4 characters from the end of the string, then (because no length has been specified) returns all the remainder until the end of the string. This is equivalent to: %date:~-4,4%

The drawback here is you cannot dynamically set the 'start' and 'length'. For this we need to use delayed expansion, which I'll get back to in a later post!

Until then, thoughts?

Friday 18 July 2008

Batch Programming Tip#10: Making and calling a subroutine (part 2)

Let's see how can pass arguments to our get_date subroutine to change date format. For instance, we will be able to choose whether the day or month comes first in our output string and which separator (if any) we wish to use.
Beware that date /T is probably locale dependent. On my system the date is output in the following format 'day. dd/mm/yyyy' e.g. mon. 14/07/2008


@echo off

:show_date
call :get_date / 0 1
echo Date: %_date%
goto eof

:get_date
set delim=%~1
set order=%~2
set show_day=%~3

echo delim=%delim% and order=%order% and show_day=%show_day%

for /F "tokens=1,2,3,4 delims=/ " %%d in ('date /T') do (
set day=%%d
set dd=%%e
set mm=%%f
set yyyy=%%g
)

set _date=%dd%%delim%%mm%%delim%%yyyy%
if "%order%"=="1" set _date=%mm%%delim%%dd%%delim%%yyyy%
if "%show_day%"=="1" set _date=%day% %_date%
goto blackhole

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole


The get_date subroutine has changed considerably.

First, we get three possible arguments: delimiter, order (either day/month or month/day) and show_day (whether or not to show the day: 'mon.' for instance). You retrieve the arguments in the same way as you would for batch command-line arguments (using %~1, etc.).

These arguments are appended to the call to the subroutine: call :get_date / 0 1.

Second, we split the date string into four parts day (mon.), dd (14), mm (07), yyyy (2008).

Finally, we build the %_date% variable while taking into account the various arguments. If %order% is set to 1 we reverse dd and mm order. If show_day is set to 1, we prefix the date with the day.

That's it.

Thoughts?

Thursday 17 July 2008

Batch Programming Tip#10: Making and calling a subroutine (part 1)

It looks like quite a few people are wondering how to write a subroutine, and how to pass it arguments. So let's write a small subroutine. You can't actually 'return' a value from the subroutine in the usual sense of the term. You can however set one or more variables within the subroutine which can then be used by the caller.

Let's imagine we need to write a subroutine that will retrieve the current date for us.

Let's start our batch by writing the following subroutine which will compute the date and store it in the %_date% variable.

@echo off

:get_date
for /F "tokens=2 delims= " %%d in ('date /T') do (
set _date=%%d
)
goto blackhole

:blackhole

What happens here is a slightly more complex for /F construct than we saw previously.
date /T outputs the current date, for instance as follows: mon. 14/07/2008
The for construct then effectively splits the string using the space character as the delimiter (this will leave us with 2 tokens: 'mon.' and '14/07/2008' but without the quotes). It then takes the second token (tokens=2) which is stored in %%d. Neat!

Obviously, if you run this script 'as-is', you won't actually 'see' anything happen, although the script will have computed the 'date' and stored it in the %_date% variable.

I do have an inkling that date format varies according to system locale. For instance you may find that on some systems you will output day/month/year and on others month/day/year according to your country/language settings.

Right, now let's add in some script to call the subroutine.


@echo off

:show_date
call :get_date
echo Date: %_date%
goto eof

:get_date
for /F "tokens=2 delims= " %%d in ('date /T') do (
set _date=%%d
)
goto blackhole

:eof
echo Press any key to quit...
pause > NUL
goto blackhole

:blackhole

Calling the subroutine is done in much the same way as calling an external batch but with an extra colon: call :get_date. This sets the %_date% variable which can then be shown from within the calling routine.

Note the importance of the 'goto blackhole' instruction at the end of the subroutine, this is what makes you 'return' to the calling code. You can alternatively use goto:EOF or goto :EOF. (Note that this is NOT the same as goto eof without the colon, which leads to the "Press any key" section of this script.)

One way to improve our subroutine would be to add arguments to allow for various date formats.

Thoughts?

Wednesday 16 July 2008

Batch programming tip#09: Using FOR /D

This is a basic variation of the for loop. Add the /D modifier to loop through directories.

The following script shows all the subdirectories of the current directory (the directory the batch is running from).

@echo off

:action
for /D %%l in (*) do (
echo Directory: %%l
)
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole


Let's simply list all directories and all files in those directories:

@echo off

:action
for /D %%l in (*) do (
echo Directory: %%l
cd %~dp0\%%l
for %%f in (*.*) do (
echo File: %%f
)

)
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole

Well, that's it for now.

Thoughts?

Tuesday 15 July 2008

Batch programming tip#08 (part 3): Reading from a file - Looping

This post will bring an end (I think) to this thread about file reading using batch.

To use the loop command on a file we simply add /F in our FOR loop construct like so:

@echo off

:init_vars
if exist file1.txt goto action
echo Oops. file1.txt doesn't exist. Please create it or change file name.
goto eof

:action
for /F %%l in (file1.txt) do (
echo Content: %%l
)
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole

This will probably work with most configuration files you might use. There is one additional parameter that's really useful though, especially if your lines contain spaces. The FOR loop will by default only return the first token up to a delimiter character. The default delimiter characters are space and tab. This means the script above will only return the first word of any line containing spaces.

To avoid this (usually unwanted) behaviour, use the delims parameter and set it to empty as in the following code:

@echo off

:init_vars
if exist file1.txt goto action
echo Oops. file1.txt doesn't exist. Please create it or change file name.
goto eof

:action
for /F "delims=" %%l in (file1.txt) do (
echo Content: %%l
)
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole


Notice how we have added to our for construct:
for /F "delims=" %%l in (file1.txt) do

You can set "delims=" to whatever you want in effect, you could for instance use comma instead: "delims=,".

Well, I think that's it, you can of course take file reading much further if you want. In that case, you might want to check Rob van der Woude's comprehensive page about NT FOR syntax. Enjoy!

More shortly about how to loop through directories.

Thoughts in the meantime?

Monday 14 July 2008

Batch programming tip#08 (part 2): Reading from a file - Looping

So, let's see how we can loop through information.
The following script is the same as the previous but I have added a loop construct which will loop through our file_content variable (the first line of the file).

@echo off

:init_vars
if exist file1.txt goto action
echo Oops. file1.txt doesn't exist. Please create it or change file name.
goto eof

:action
set /P file_content=<file1.txt
for %%l in (%file_content%) do (
echo Content: %%l
)
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole

The loop construct is simple: for %%varname in (%var%) do ( ..[action]..)
The parentheses around the %var% are not in there just for form, you really need to remember them or your batch will crash.

To test it try using a file that contains a first line with spaces in it (e.g. The quick brown fox jumps over the lazy dog) and you will see that each word of the first line of the file will appear on a line of its own.

Excellent, the next step will be to loop through all the lines in a file.

Thoughts in the meantime?

Sunday 13 July 2008

Batch programming tip#08: Reading from a file

Reading from file can sometimes be really useful. For example, you could imagine one process was to output lots of file names to a given file (let's call it file1.txt) and then that our batch would jump in there and retrieve those file names and print up whatever is in them (obviously in a real-world case scenario, you would want to handle the files and do something with them, e.g. archive them to a different location or whatever).

To read content from a file, we set a variable using /P and the < sign after the usual = sign.

The following code does this.

@echo off

:init_vars
set /P file_content=<file1.txt
goto action

:action
echo File content: %file_content%
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole

Note that if file1.txt doesn't exist an error message will show and the variable %file_content% will be empty.

Hey presto, we got something out of the file. This is great... except: we are only getting hold of the first line.

In the two following posts, I will explain the loop construct and how to use it to read all the lines from the file.

Thoughts in the meantime?

Saturday 12 July 2008

Batch tip#07 part 2: comparing files by size

Now we have seen how to retrieve the length of a file passed as argument, let's see how we can use this.

The code below does the following:

1. Command-line check
The process checks for command-line arguments. It expects two existing files otherwise shows an error.
To check whether a file exists, simply use if exist %file%.

2. Compare sizes
The batch retrieves and compares argument file sizes. To do this we use %~z1 and %~z2 which return the file sizes of command line arguments 1 and 2 respectively.

3. Take action
Finally, it outputs an adequate message. This is obviously the bit where you should include appropriate actions.

The code


@echo off

:param_check
if "" == "%1" goto invalid_call
if "" == "%2" goto invalid_call
goto file_one

:file_one
if exist %1 goto file_two
set file_path=%1
goto show_error

:file_two
if exist %2 goto run_content
set file_path=%2
goto show_error

:run_content
if %~z1==%~z2 goto same_size
if %~z1 LSS %~z2 goto first_smaller
goto second_smaller

:same_size
echo Both files are of same size.
goto eof

:first_smaller
echo %1 is smaller than %2
goto eof

:second_smaller
echo %2 is smaller than %1
goto eof

:show_error
echo File not found: "%file_path%"
goto eof

:invalid_call
echo Please call with the following parameters:
echo [1] the first file name
echo [2] the second file name
goto eof

:eof
echo Press any key to close window...
pause > nul
goto blackhole

:blackhole


To run this, simply use a second .bat file containing something like:

@echo off
call comp_files file1.txt file2.txt

Where file1.txt and file2.txt are replaced with the relative or absolute paths of the files your are comparing.

Simple as that!

Thoughts?

Friday 11 July 2008

The DNS uproar

As you probably already know, security researcher Dan Kaminsky (and his team I believe) recently reported a DNS vulnerability affecting most DNS servers world-wide. They have also released patches for all platforms before actually revealing details about the vulnerability. In fact, they are leaving people the time to upgrade their systems, before giving us any of the secret facts.

And it doesn't stop there! If you check out the Doxpara research site (at: http://www.doxpara.com), you will find an online DNS checker which will tell you whether your DNS server seems safe or not.

If you are like me your DNS requests might get routed to one of several DNS servers, so this can require several online "tests".

Some people seem to be having issues with ZoneAlarm (as reported by Nathan McFeters at ZDnet) but it seems workarounds are already available. So this really does seem minor to me.

Will this start to pave the way to responsible hack disclosures?

Thursday 10 July 2008

Batch programming tip#07: Retrieving argument filesize

Imagine you are using a file as argument (this can also be %0 of course) and you would like to know the file's size in bytes.

This is an example of how to do this:

@echo off

:action
echo File size of currently running batch file: %~z0
goto eof

:eof
echo Press a key to quit...
pause > NUL
goto blackhole

:blackhole

Using %~z0 retrieves the file size of the currently running batch which should be 164 (unless of course you have added in or removed extra line breaks, comments, etc.)

One reason to use file size would be, for instance, you might want a batch to once use a given configuration file, but then use another the next time, and then to switch back to the first the time after that. If these configuration files are definitely of different size, you can use file size to operate the swap.

Voilà!

Thoughts?

Wednesday 9 July 2008

Are you ready for iPhone 3G?

Here it comes, the iPhone 3G is finally being launched in the remaining European countries!!

In Belgium, specific legislation means it cannot be sold exclusively.
But at a selling price of a whopping 525 to 615 euro (!), approximately 4 times the US price, will the Belgians be ready for it?

Tuesday 8 July 2008

Blogger Quicklist - Making a blog "work"

Blogging - and bloggers - have got me thinking about how to make a blog 'work'. I have had several blogs, and although lots of energy, time and effort can ensure some readership it's very difficult to keep a blog going in the long-run.

So, here are a few things that seem important to me:
1. Use a main thread in your blog e.g. write about your work OR write about your private life OR write about a particular passion and anything related OR ... but don't mix them up in the same blog (or only do so rarely, e.g. explain you haven't posted for a week because you have been on holiday, that sort of thing);
2. Don't post just to post, if inspiration gets low, just let it go for a while
3. Choose a good blog title, only use your name if you are already a well-known blogger figure
4. Go crazy with labels, use lots of them
5. Use blogger's label list (and/or turn it into a label cloud)
6. Use the post options to automatically schedule post publication (for instance, it may be easier to write several posts at the week-end and schedule them to be published during the week) - this way users don't get overloaded with new posts to read, and you don't feel obligated to write more during the week.
7. Don't let posts get too lengthy

Well, there must be lots of other obvious guidelines which I didn't mention here. But I guess it's a start! I can't really talk about how to increase blog participation (e.g. comments, emails, etc.) as I have a very low participative rate on this blog. But one of the tricks is to ask questions every time you end a post like so:

What 'guidelines' do you follow to make your blog successful?

Sunday 6 July 2008

Batch programming tip#06: Getting the batch file path

Ok. Well, it's been a while since I posted anything to do with actual programming, and I have missed it. So here goes with the next batch programming trick planned: how to retrieve the batch file path. That is: the path where the batch file being run is located.

This is a dead easy variable: %~dp0. We'll get back to what this sequence actually means in a later post but you will notice how much it looks like the argument 0 (%0 or %~0 in this case) I mentioned in an earlier post. It's just had a couple of characters added in (dp).

So, now for a simple echo example:


@echo off

:action
echo Current batch run path: %~dp0
goto eof

:eof
echo Press a key to quit...
pause > NUL
goto blackhole

:blackhole

This looks too simple to actually be of any use but actually using the current run path can be very handy if you store configuration or content files in the same directory as your batch file (or a subdirectory thereof)!

More about that soon.

Thoughts?

Saturday 5 July 2008

Increasing Flash searchability

One of the main concerns when building a website (blogs, wikis, ... included) is of course to make sure all data on it is readily available. Which basically means the search engines need to be able to crawl the data in a way that makes it possible to extract content and relevant keywords.

If you're using plain HTML for instance, this is pretty easy.

It does get more complicated if you're using Flash but that may be about to change.
The following article (dated: 2006) describes what you can do (or had to do in the past) to make sure your Flash-enabled website pages get (got) the correct (or increased) search rankings:
http://www.adobe.com/devnet/flash/articles/flash_searchability.html

However, there have been several reports this week that Google, Yahoo and Adobe are teaming up to make Flash (SWF) files easier to crawl in-depth - more like an HTML page crawl basically.

In eWeek's article, Bill Hunt (president of Global Strategies International) is quoted as saying:

[The most significant aspect of the announcement] "is that this is not a change the site owners have to implement but that Google, and soon Yahoo, have this baked into their crawl systems and can interact with the SWF format just as a visitor to the site would, allowing them to get deep into the content discovering links and content that have previously been hidden from search engines."


This is a win-win-win situation where both the search engines and Adobe will benefit from an enhanced user experience (thus the third 'win'). And Adobe will subsequently be edging nearer to a position where it could claim to be more than a de facto standard for rich internet applications.

So, will this make the RIA era boom? And should Adobe Flash applications become an official web standard?

Browser Security

Ryan Naraine discussed a recent study about browser security in a recent article.

Before we start let's point out the following:

The entire report is a valuable read on the state of browser security but, as Brian Krebs points out, the conclusions should be considered conservative since it does not include information on vulnerable plugins (think Flash Player, Adobe Reader, Java, QuickTime, etc). Also, bear in mind that these numbers only represent Google users.

So we're really talking specifically about the browser applications and not the browsing experience as a whole.


We discovered that at most 83.3% of Firefox users, 65.3% of Safari users, 56.1% of Opera users, and 47.6% of Internet Explorer users were using the latest most secure browser version on any day between January 2007 to June 2008. For the latest version analysis of Safari, we only considered the date range Dec 2007 to June 2008, when Safari version 3 became widespread.

I suspect Internet Explorer's surprisingly bad results are due to poor adoption of the browser's latest version IE7. And this will be linked to:
- people who can't upgrade to IE7 because their system requirements cannot be met (e.g. anyone running Win2000);
- people who won't upgrade to IE7 because they found it changes their browsing experience too much (e.g. too different from the user perspective: tabs, new menus, etc. and/or technical issues: breaks current web-based applications which need to be upgraded to ensure IE7 compatibility).

I must say of late Microsoft upgrades have entailed lots of extra unexpected technical work. Just think back to XP SP2 (a real pain in the neck). These new systems require security tweaking everytime - it's no wonder companys and users are slowly changing their ways and going for backward-compatible and standard compliant systems.

And it makes me wonder. Should large corporations be allowed to make application upgrades which will affect everyone actually developing anything for use with said application? Aren't systems today being designed to be so secure at the user's expense, making them difficult to use? Is it not actually counterproductive if users just get annoyed and frustrated with over-secure systems (esp. as these systems are still vulnerable to attacks anyway)?

Perhaps we should just turn to some form of mandatory training about the risks posed by accessing the Internet, how to reduce these risks and how to recognize certain types of attacks/infections, and how to check systems for known infections.

What do you think?

Tuesday 1 July 2008

Label cloud

I am probably centuries late on this one but I simply have to share.
I had never payed much attention but when I came across http://acedar.blogspot.com/ and saw the label cloud I just had to investigate.
It hardly took any effort at all, simply check out:
http://phy3blog.googlepages.com/Beta-Blogger-Label-Cloud.html
and "build" your own label cloud within minutes.

The best effect is achieved by simply leaving the labels in alphabetical order, this ensures a nice mix of larger/smaller lettering.

The beauty in the blogger widgets is you can change them (i.e. via the HTML code interface), and then still move them about (via the layout interface) without losing your own changes. Great!
Online Marketing
Add blog to our blog directory blog search directory Blog Directory Blogarama - The Blog Directory