User:Dad

From WPKG | Open Source Software Deployment and Distribution
Jump to: navigation, search

Daniel Dehennin


Contents

[edit] Using unattended script

I'm using unattened script from Rainer Meier with some modifications:

[edit] install.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set PROGRAM_NAME=Application

REM Command to run
set CMD32=installer.exe
set CMD64=%CMD32%
set CMD_PATH=%~dp0
set CMD_OPTS=/SILENT

REM Unattended installer
set INSTALLER=unattended.cmd
set INSTALLER_TYPE=custominstall
set INSTALLER_LOC=%~dp0

REM OS specific path/CMD
REM WARNING: %ProgramFiles(x86)% misclose blocs
REM use dos function to bypass DOS parser limitation
REM :ospath
REM
REM ver | find "version 5.1" > NUL && (
REM     SET CMD_PATH=%CMD_PATH%winxp
REM     SET CMD_32=install-xp-32.exe
REM     SET CMD_64=install-xp-64.exe
REM )
REM
REM ver | find "version 6.0" > NUL && (
REM     SET CMD_PATH=%CMD_PATH%winvista
REM     SET CMD_32=install-vista-32.exe
REM     SET CMD_64=install-vista-64.exe
REM )
REM
REM ver | find "version 6.1" > NUL && (
REM     SET CMD_PATH=%CMD_PATH%win7
REM     SET CMD_32=install-7-32.exe
REM     SET CMD_64=install-7-64.exe
REM )
 
:install
echo Installing %PROGRAM_NAME%
 
call "%INSTALLER_LOC%%INSTALLER%" %INSTALLER_TYPE% "%CMD32%" "%CMD64%" "%CMD_PATH%" "%CMD_OPTS%"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit] remove.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set PROGRAM_NAME=Program

REM 32/64 bit PATH
IF "%ProgramFiles(x86)%" NEQ "" (
    call :64bits
) else (
    call :32bits
)

REM Command to run
set CMD32=uninstaller.exe
set CMD64=%CMD32%
set CMD_PATH=%PROG_PATH%\%PROGRAM_NAME%
set CMD_OPTS=/S

REM Unattended uninstaller
set INSTALLER=unattended.cmd
set INSTALLER_TYPE=customuninstall
set INSTALLER_LOC=%~dp0
 
 
:remove
echo Removing %PROGRAM_NAME%
 
call "%INSTALLER_LOC%%INSTALLER%" %INSTALLER_TYPE% "%CMD32%" "%CMD64%" "%CMD_PATH%" "%CMD_OPTS%"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%
 
 
:32bits
SET PROG_PATH=%ProgramFiles%
GOTO :EOF
 
 
:64bits
SET PROG_PATH=%ProgramFiles(x86)%
GOTO :EOF

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit] unattended.cmd

The engine doing the hard work

@echo off

REM Usage:

REM unattended.cmd <type> <32-bit-installer> <64-bit-installer>
REM                [installer-location [custom-options]]

REM where type is one of
REM     msiinstall       Install the given MSI package
REM     msiupdate        Update the given MSP package
REM     msiuninstall     Uninstall the given MSI package
REM     install4j        Install4J setup
REM     innoinstall      Inno setup installer
REM     innouninstall    Inno setup uninstaller
REM     installshield    Install shield
REM     nsis             Nullsoft install system (NSIS)
REM     custominstall    Custom installer - options required in this case
REM     customuninstall  Custom installer - options required in this case

REM 32-bit-installer     Full file name (including extension) of 32-bit installer
REM 64-bit-installer     Full file name (including extension) of 64-bit installer
REM installer-location   Path where the installers are stored, if empty assumes
REM                      directory where install.cmd is
REM custom-options       Replace the default installer options with the ones given

REM Do not export variables
SETLOCAL

REM Global variables
set INSTALL_CMD=
set EXIT_CODE=0

REM Get command type
set TYPE=%~1

REM Get 32-bit installer name
set CMD32=%~2

REM Get 64-bit installer name
set CMD64=%~3

REM get file path
set INSTALLER_PATH=%~4

REM get unattended path
set SCRIPTS_PATH=%~dp0
 
set OPTIONS=
if not "%~5" == "" (
set OPTIONS=%~5
)

 
REM Detect which system is used
if not "%ProgramFiles(x86)%" == "" goto 64bit
goto 32bit

 
REM ##########################################################################
REM 64-bit system detected
REM ##########################################################################
:64bit
REM Determine 64-bit installer to be used
echo 64-bit system detected.
REM set INSTALLER64=
if not "%CMD64%" == "" (
set INSTALLER64=%CMD64%
) else (
REM Use 32-bit installer if available, no 64-bit installer available.
if not "%CMD32%" == "" (
echo Using 32-bit installer, no 64-bit installer specified.
set INSTALLER64=%CMD32%
) else (
echo Neither 64-bit nor 32-bit installer specified. Exiting.
goto usage
)
)
set INSTALL_CMD=%INSTALLER_PATH%%INSTALLER64%
goto installerselection

 
REM ##########################################################################
REM 32-bit system detected
REM ##########################################################################
:32bit
REM Determine 32-bit installer to be used
echo 32-bit system detected.
set INSTALLER32=
if not "%CMD32%" == "" (
set INSTALLER32=%CMD32%
) else (
echo No 32-bit installer specified. Exiting.
exit /B 96
)
set INSTALL_CMD=%INSTALLER_PATH%%INSTALLER32%

REM ##########################################################################
REM select installer/uninstaller system with pre-install/remove
REM ##########################################################################
:installerselection
 
if /i "%TYPE%" == "msiuninstall"    goto preremove
if /i "%TYPE%" == "innouninstall"   goto preremove
if /i "%TYPE%" == "customuninstall" goto preremove
 
:preinstall
REM pre-install
if exist "%INSTALLER_PATH%preinstall.cmd" (
   call "%INSTALLER_PATH%preinstall.cmd"
) else (
  if exist "%SCRIPTS_PATH%preinstall.cmd" (
     call "%SCRIPTS_PATH%preinstall.cmd"
  ) else (
    if exist "%INSTALL_CMD%-preinstall.cmd" (
       call "%INSTALL_CMD%-preinstall.cmd"
    )
  )
)
goto checkinstaller
 
:preremove
REM pre-install
if exist "%INSTALLER_PATH%preremove.cmd" (
   call "%INSTALLER_PATH%preremove.cmd"
) else (
  if exist "%SCRIPTS_PATH%preremove.cmd" (
     call "%SCRIPTS_PATH%preremove.cmd"
  ) else (
    if exist "%INSTALL_CMD%-preremove.cmd" (
       call "%INSTALL_CMD%-preremove.cmd"
    )
  )
)
 
:checkinstaller
REM Check if installer is valid
if not exist "%INSTALL_CMD%" (
echo Installer "%INSTALL_CMD%" cannot be found! Exiting.
exit /B 97
)
 
if /i "%TYPE%" == "msiinstall"    goto msiinstaller
if /i "%TYPE%" == "msiupdate"     goto msiupdate
if /i "%TYPE%" == "install4j"     goto install4j
if /i "%TYPE%" == "innoinstall"   goto innoinstaller
if /i "%TYPE%" == "installshield" goto installshieldinstaller
if /i "%TYPE%" == "nsis"          goto nsisinstaller
if /i "%TYPE%" == "custominstall" goto custominstaller
 
if /i "%TYPE%" == "msiuninstall"    goto msiuninstaller
if /i "%TYPE%" == "innouninstall"   goto innouninstaller
if /i "%TYPE%" == "customuninstall" goto customuninstaller
 
goto usage
 
:msiinstaller
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" msiexec /qn /norestart /i "%INSTALL_CMD%" %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
 
:msiupdate
echo Updating "%INSTALL_CMD%"
start /wait "Software update" /D"%INSTALLER_PATH%" msiexec /qn /norestart /update "%INSTALL_CMD%" %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
 
:msiuninstaller
echo Uninstalling "%INSTALL_CMD%"
start /wait "Software uninstallation" /D"%INSTALLER_PATH%" msiexec /qn /norestart /x "%INSTALL_CMD%" %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postremove
 
 
:install4j
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" -q %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
 
:innoinstaller
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" /silent /verysilent /norestart /sp- %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
:innouninstaller
echo Uninstalling "%INSTALL_CMD%"
start /wait "Software uninstallation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" /silent /verysilent /norestart /sp- %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postremove
 
 
:installshieldinstaller
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" /s %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
 
:nsisinstaller
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" /S %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
:custominstaller
if "%OPTIONS%" == "" goto usage
echo Installing "%INSTALL_CMD%"
start /wait "Software installation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postinstall
 
:customuninstaller
if "%OPTIONS%" == "" goto usage
echo Uninstalling "%INSTALL_CMD%"
start /wait "Software uninstallation" /D"%INSTALLER_PATH%" "%INSTALL_CMD%" %OPTIONS%
set EXIT_CODE=%ERRORLEVEL%
goto postremove
 
:usage
echo Usage:
echo "%~nx0 <type> <32-bit-installer> <64-bit-installer> [installer-location [custom-options]]"
echo where type is one of
echo     msiinstall       Install the given MSI package
echo     msiupdate        Update the given MSP package
echo     msiuninstall     Uninstall the given MSI package
echo     install4j        Install4J setup
echo     innoinstall      Inno setup installer
echo     innouninstall    Inno setup uninstaller
echo     installshield    Install shield
echo     nsis             Nullsoft install system (NSIS)
echo     custominstall    Custom installer - options required in this case
echo     customuninstall  Custom installer - options required in this case
 
echo 32-bit-installer     Full file name (including extension) of 32-bit installer
echo 64-bit-installer     Full file name (including extension) of 64-bit installer
echo installer-location   Path where the installers are stored, if empty assumes
echo                      directory where install.cmd is
echo custom-options       Replace the default installer options with the ones given
exit /B 99
 
:postinstall
REM post-install
if exist "%INSTALLER_PATH%postinstall.cmd" (
   call "%INSTALLER_PATH%postinstall.cmd"
) else (
  if exist "%SCRIPTS_PATH%postinstall.cmd" (
     call "%SCRIPTS_PATH%postinstall.cmd"
  ) else (
    if exist "%INSTALL_CMD%-postinstall.cmd" (
       call "%INSTALL_CMD%-postinstall.cmd"
    )
  )
)
goto end
 
:postremove
REM post-remove
if exist "%INSTALLER_PATH%postremove.cmd" (
   call "%INSTALLER_PATH%postremove.cmd"
) else (
  if exist "%SCRIPTS_PATH%postremove.cmd" (
     call "%SCRIPTS_PATH%postremove.cmd"
  ) else (
    if exist "%INSTALL_CMD%-postremove.cmd" (
       call "%INSTALL_CMD%-postremove.cmd"
    )
  )
)
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM"
REM comment-end: ""
REM End:

[edit] application layout

The basic layout of an application is the following:

<Application>
├── <version prod>
│   ├── <installer x32>
│   ├── <insaller x64>
│   ├── install.cmd
│   ├── postinstall.cmd
│   ├── remove.cmd
│   └── unattended.cmd
├── <version test>
│   ├── <insaller x32>
│   ├── <insaller x64>
│   ├── install.cmd
│   ├── postinstall.cmd
│   ├── remove.cmd
│   └── unattended.cmd
├── install.cmd         <----- call <version prod>/install.cmd
└── remove.cmd          <----- call <version prod>/remove.cmd

The top level install.cmd and remove.cmd only call what I define the version in production. This permit to have static link to install something.

├── 7zip
│   ├── 9.13
│   │   ├── 7z913.msi
│   │   ├── 7z913-x64.msi
│   │   ├── 7zip.reg
│   │   ├── install.cmd
│   │   ├── postinstall.cmd
│   │   ├── remove.cmd
│   │   └── unattended.cmd
│   ├── 9.17
│   │   ├── 7z917.msi
│   │   ├── 7z917-x64.msi
│   │   ├── 7zip.reg
│   │   ├── install.cmd
│   │   ├── postinstall.cmd
│   │   ├── remove.cmd
│   │   └── unattended.cmd
│   ├── install.cmd
│   └── remove.cmd
├── adobe
│   ├── flash
│   │   ├── 10.1
│   │   │   ├── ie
│   │   │   │   ├── install.cmd
│   │   │   │   ├── install_flash_player_10_active_x.msi
│   │   │   │   ├── remove.cmd
│   │   │   │   └── unattended.cmd
│   │   │   └── mozilla
│   │   │       ├── install.cmd
│   │   │       ├── install_flash_player_10_plugin.msi
│   │   │       ├── remove.cmd
│   │   │       └── unattended.cmd
│   │   ├── install.cmd
│   │   └── remove.cmd
│   └── reader
│       ├── 9.3.0
│       │   ├── acroread.msi
│       │   ├── data1.cab
│       │   ├── install.cmd
│       │   ├── postinstall.cmd
│       │   ├── postremove.cmd
│       │   ├── remove.cmd
│       │   └── unattended.cmd
│       ├── 9.3.2
│       │   ├── adberdrupd932_all_incr.msp
│       │   ├── install.cmd
│       │   ├── postinstall.cmd
│       │   ├── postremove.cmd
│       │   ├── preinstall.cmd
│       │   ├── remove.cmd
│       │   └── unattended.cmd
│       ├── 9.3.4
│       │   └── AdbeRdrUpd934_all_incr.msp
│       ├── 9.4.0
│       │   ├── acroread.msi
│       │   ├── data1.cab
│       │   ├── install.cmd
│       │   ├── postinstall.cmd
│       │   ├── postremove.cmd
│       │   ├── remove.cmd
│       │   └── unattended.cmd
│       ├── install.cmd
│       └── remove.cmd
├── template                                   <-- template source
│   ├── install.cmd
│   ├── postinstall.cmd
│   ├── postremove.cmd
│   ├── remove.cmd
│   └── unattended.cmd
[...]

Each version directory has a copy of the unattended.cmd engine, they are autonomous, I can copy each one on an USB key and use it directly.

NB: The template source is the place where I update unattended.cmd, I distribute it in each folder with the following (linux) command:

moi@work:~$ find . -type f -name 'unattended.cmd' -exec cp -f template/unattended.cmd {} \;

[edit] Example with adobe reader 9.4.0

[edit] XML package

<?xml version='1.0' encoding='utf-8'?>
<packages>
  <package
      id='adobe-reader-9'
      name='Adobe Reader 9'
      revision='9.4.0.1'
      reboot='false'
      priority='100'>
 
    <check type='uninstall' condition='exists' path='Adobe Reader 9.4.0 - Français'/>
    <check type='logical' condition='or'>
      <check type='file' condition='versiongreaterorequal'
             path='%ProgramFiles%\Adobe\Reader 9.0\Reader\Acrord32.exe'
             value='9.4.0.195'/>
      <check type='file' condition='versiongreaterorequal'
             path='%ProgramFiles(x86)%\Adobe\Reader 9.0\Reader\Acrord32.exe'
             value='9.4.0.195'/>
    </check>
 
    <install cmd='%SOFTWARE%\adobe\reader\9.4.0\install.cmd'/>
    <upgrade cmd='%SOFTWARE%\adobe\reader\9.4.0\install.cmd'/>
    <remove cmd='%SOFTWARE%\adobe\reader\9.4.0\remove.cmd'/>
 
  </package>
</packages>

[edit]  %SOFTWARE%\adobe\reader\install.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set CMD_PATH=%~dp0
 
set APPLI_VERSION=9.4.0
 
:install
 
call "%CMD_PATH%\%APPLI_VERSION%\install.cmd"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit]  %SOFTWARE%\adobe\reader\remove.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set CMD_PATH=%~dp0
 
set APPLI_VERSION=9.4.0
 
:remove
 
call "%CMD_PATH%\%APPLI_VERSION%\remove.cmd"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit]  %SOFTWARE%\adobe\reader\9.4.0\install.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set PROGRAM_NAME=Acrobat Reader 9.4.0

REM Command to run
set CMD32=acroread.msi
set CMD64=%CMD32%
set CMD_PATH=%~dp0
set CMD_OPTS=/qn /norestart ALLUSERS=2 EULA_ACCEPT=YES SUPPRESS_APP_LAUNCH=YES AgreeToLicense=YES ENABLE_CACHE=NO

REM Unattended installer
set INSTALLER=unattended.cmd
set INSTALLER_TYPE=msiinstall
set INSTALLER_LOC=%~dp0
 
 
:install
echo Installing %PROGRAM_NAME%
 
call "%INSTALLER_LOC%%INSTALLER%" %INSTALLER_TYPE% "%CMD32%" "%CMD64%" "%CMD_PATH%" "%CMD_OPTS%"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit]  %SOFTWARE%\adobe\reader\9.4.0\postinstall.cmd

@echo off

REM Do not export variables
SETLOCAL

REM 32/64 bit PATH
IF "%ProgramFiles(x86)%" NEQ "" (
    call :64bits
) else (
    call :32bits
)

REM Adobe Reader registery hive
SET READER_REG_PATH=%SOFT_PATH%\Adobe Reader\9.0

REM Adobe Reader program path
SET READER_PROG_PATH=%PROG_PATH%\Adobe\Reader 9.0

REM Win7
ver | find "version 6.1" 2>NUL > NUL && (
    SET AllUsersDesktop=%PUBLIC%\Desktop
    SET UserDesktop=%UserProfile%\Desktop
) || (
    REM Francais/English
    net localgroup Administrateurs 2> NUL > NUL && (
        SET AllUsersDesktop=%AllUsersProfile%\Bureau
        SET UserDesktop=%UserProfile%\Bureau
    ) || (
        SET AllUsersDesktop=%AllUsersProfile%\Desktop
        SET UserDesktop=%UserProfile%\Desktop
    )
)
 
echo Remove Desktop Shortcut
%ComSpec% /c del /F /Q "%AllUsersDesktop%\Adobe Reader*.lnk" 2> NUL > NUL
%ComSpec% /c del /F /Q "%UserDesktop%\Adobe Reader*.lnk" 2> NUL > NUL
 
echo Disable EULA
reg add "%READER_REG_PATH%\AdobeViewer" /v EULA /t REG_DWORD /d "00000001" /f 2> NUL > NUL
reg add "%READER_REG_PATH%\AdobeViewer" /v Launched /t REG_DWORD /d "00000001" /f 2> NUL > NUL
 
echo Disable Beyong
reg add "%READER_REG_PATH%\Downtown" /v bDontShowAtLaunch /t REG_DWORD /d "00000001" /f 2> NUL > NUL
 
echo Disable going online
reg add "%READER_REG_PATH%\Downtown" /v GoOnline /t REG_DWORD /d "00000000" /f 2> NUL > NUL
 
echo Disable Speed Launcher
reg delete "%RUN_PATH%" /v "Adobe Reader Speed Launcher" /f 2> NUL > NUL

REM FIXME with 64 bit use %ProgramFiles(x86)% ?
echo Turn off automatic update
move /Y "%READER_PROG_PATH%\Reader\plug_ins\updater.*" "%READER_PROG_PATH%\Reader\Optional" 2> NUL > NUL
 
echo Disable Adobe ARM
reg delete "%RUN_PATH%" /v "Adobe ARM" /f 2> NUL > NUL
 
:end
exit /B %ERRORLEVEL%
 
:32bits
SET SOFT_PATH=HKLM\SOFTWARE\
SET RUN_PATH=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
SET PROG_PATH=%ProgramFiles%
GOTO :EOF
 
:64bits
SET SOFT_PATH=HKLM\Software\Wow6432Node\
SET RUN_PATH=HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
SET PROG_PATH=%ProgramFiles(x86)%
GOTO :EOF

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit]  %SOFTWARE%\adobe\reader\9.4.0\remove.cmd

@echo off

REM Do not export variables
SETLOCAL
 
set PROGRAM_NAME=Acrobat Reader 9.4.0

REM Command to run
set CMD32=acroread.msi
set CMD64=%CMD32%
set CMD_PATH=%~dp0
set CMD_OPTS=

REM Unattended uninstaller
set INSTALLER=unattended.cmd
set INSTALLER_TYPE=msiuninstall
set INSTALLER_LOC=%~dp0
 
 
:remove
echo Removing %PROGRAM_NAME%
 
call "%INSTALLER_LOC%%INSTALLER%" %INSTALLER_TYPE% "%CMD32%" "%CMD64%" "%CMD_PATH%" "%CMD_OPTS%"
set EXIT_CODE=%ERRORLEVEL%
 
 
:end
exit /B %EXIT_CODE%

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:

[edit]  %SOFTWARE%\adobe\reader\9.4.0\postremove.cmd

@echo off

REM Do not export variables
SETLOCAL

REM 32/64 bit PATH
IF "%ProgramFiles(x86)%" NEQ "" (
    call :64bits
) else (
    call :32bits
)

REM Adobe Reader program path
SET READER_PROG_PATH=%PROG_PATH%\Adobe\Reader 9.0

REM Remove remaining directories
rd /S /Q "%READER_PROG_PATH%" > NUL
 
:end
exit /B %ERRORLEVEL%
 
:32bits
SET PROG_PATH=%ProgramFiles%
GOTO :EOF
 
:64bits
SET PROG_PATH=%ProgramFiles(x86)%
GOTO :EOF

REM End of local variables
ENDLOCAL

REM Local Variables:
REM mode: cmd
REM comment-start: "REM "
REM comment-end: ""
REM End:
Retrieved from "http://wpkg.org/User:Dad"
Personal tools
Namespaces
Variants
Actions
Navigation
ideas?
Toolbox