3

I have written a very simple (but I believe very useful) PowerShell script and created an installer for it in form of .cmd file. The distribution contains two .cmd files and two .ps1 files. Currently the installer downloads all required files from github.

My goal is to make the installer self-contained so people can use it even behind a strict firewall.

One approach could be like this:

echo param(>!filename!
echo     [string] $pfilename>>!filename!
echo )>>!filename!
...

But this approach requires escaping special characters which may turn very complex. Besides, it needs to be automated somehow in order to be useful.

Another approach is to include the script souce code into the .cmd file directly, mark with comments like ::begin file1 and ::end file1 and then extract it. But how?

My first thought was to look into pl2bat. But it turned out that perl has a special switch (-x) which just strips off all text before the #!perl line, and the .bat file generated by pl2bat just runs perl -x on itself. So I can't use the same approach that pl2bat uses.

Any ideas?

PS: I know about NSIS, InnoSetup and WiX. I just want my installer to be text, not binary, so everyone can see that it is harmless.

utapyngo
  • 6,946
  • 3
  • 44
  • 65
  • I believe the following question is essentially about the same: [printing a paragraph in windows batch](http://stackoverflow.com/questions/14559789/printing-a-paragraph-in-windows-batch). – Andriy M Feb 10 '13 at 10:23

1 Answers1

0

When I faced this same problem I opted to use an established standard for this purpose instead of devise a new term of my own, so I selected "resource" element of XML specification. This is my method:

@echo off
setlocal EnableDelayedExpansion

rem Extract "FirstSection.txt" and place in its own file:
call :getResource FirstSection > FirstSection.txt

rem Extract "SecondSection.txt" and place in its own file:
call :getResource SecondSection > SecondSection.txt

goto :EOF


:getResource resourceId

rem Resource data start format: ^<resource id="resourceId"^>
set start=
set lines=
for /F "tokens=1,3 delims=:=>" %%a in ('findstr /N "^</*resource" "%~F0"') do (
   if not defined start (
      if "%1" equ "%%~b" set start=%%a
   ) else (
      if not defined lines set /A lines=%%a-start-1
   )
)
set line=0
for /F "skip=%start% tokens=1* delims=]" %%a in ('find /N /V "" ^< "%~F0"') do (
   setlocal DisableDelayedExpansion
   echo(%%b
   endlocal
   set /A line+=1
   if !line! equ %lines% exit /B
)

For example:

<resource id="FirstSection">
Place here
the contents
of First Section
</resource>

<resource id="SecondSection">
The same
... for Second Section
</resource>

Antonio

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • I would use this carefully if I needed to pack XML files into my installer. Batch files are not XML, and `findstr` is not an XML parser. Moreover, I don't see where you check for the `id` attribute. – utapyngo Feb 11 '13 at 05:19
  • @utapyngo: You may include _any_ text between `" ...` command get the id attribute in `%%b`, that is, the value delimited by `=` and `>`. – Aacini Feb 12 '13 at 13:28
  • So your code will accept `` as well. – utapyngo Feb 13 '13 at 06:44
  • I mean that this will fail if my text contains the `` line (which is possible with XML files). – utapyngo Feb 13 '13 at 06:56