Today I wanted to write a simple Windows Batch file which should create some symbolic links (command: mklink). I thought that something like this is an easy job because I know the basics about batch programming – but that was obviously a mistake… Perhaps this post can help somebody else :)
I have a partition where all my projects are saved. Each project has it’s own subfolder and when the project is a web-project then there is a website-directory in it. Here a general example:
projects (E:) \01_projectname \02_projectname \website \03_projectname \website \04_projectname (and so on...) \xampp \htdocs
Last but not least there is a XAMPP directory for the XAMPP software which includes the Apache webserver, PHP, MySQL and so on – and there is a htdocs directory which includes a subfolder for each website. After the batch file was executed the htdocs directory should include some more folders like this:
\htdocs 01_projectname // linked to E:\01_projectname\website 02_projectname // linked to E:\02_projectname\website (and so on...)
I have to mention one thing: I don’t want to have more than one file for a simple task. Code and necessary information have to be put to one single file.
In the first moment this sound really easy but what if the drive letter changes after some time? Or if all project subfolders were moved to an additional subfolder? That’s why I don’t want to have an inflexible script. My first idea was to define an array and iterate over all elements but this failed – batch does not know anything about what an array is. You can only emulate one but that does not lead to a really nice code.
After some time I found the list feature but that’s not really that nice because actually you have to write all items in one single line and hey, who wants to do that? So there is the possibility to concatenate strings to create a string which is not that nice but does its job :) I think that this a lil’ bit better then try emulate an array.
Now there was the second problem: I wanted to have a pair of information in the list, the source and destination directory. But the loop did not extract the pair and throwed an error – I used here a list in a list. The workaround: I prepared the list so that two lines represent the pair of information I need and with the help of a counter variable and the modulo function there should be no problem any more.
Well, why should it be that easy? Because the command line interpreter thinks of every content in the variables that it’s a string so you cannot increment a value via
+=1. You have to use the option
/a in combination with the
set command – Nice feature, or not? ;) And what about the access to variables in a loop? You think you can do that them via
%variable_name%? Ha, you are wrong ;) But now lets have a look at the current code:
@echo off setlocal ENABLEDELAYEDEXPANSION set dirs=( set dirs=%dirs% 01_projectname\redesign\website set dirs=%dirs% 01_old set dirs=%dirs% 01_projectname\website set dirs=%dirs% 01 set dirs=%dirs% 02_projectname\website set dirs=%dirs% 02 set dirs=%dirs%) set project_dir=%~d0\ set htdocs_dir=%~d0\xampp\htdocs\ set /a counter=0 set dirA= set dirB= for %%d in %dirs% do ( set /a m="!counter!%%2" if !m!==0 ( set dirA=%%d ) else ( set dirB=%%d set tmpDir=!htdocs_dir!!dirB! if not exist !tmpDir! ( echo Creating link !dirB! mklink /J !tmpDir! !project_dir!!dirA! ) else ( echo Link !dirB! already exists ) ) set /a counter+=1 ) pause
Perhaps there are some ideas which can help others to write their batch scripts. If there are any questions about the task or the code please don’t be shy ;)