简体   繁体   中英

How to detect whether a Windows batch file is run from a ZIP archive

One of the ways our app is distributed (on Windows) is as a ZIP archive. Inside this archive is a batch file used for starting the app. The user is supposed to unzip the archive before running our app, but frequently users ignore our instructions and try to run the app without unzipping the archive first. When users do this, the app fails to start, but it's not obvious (to the user) exactly what caused the failure. We'd like to detect from within the batch file whether it's being run from inside a ZIP archive, and if so, show the user a message reminding him to unzip the archive first.

However, it's not clear at all to me how to detect this condition. While the batch variable %cmdcmdline% contains the command which ran the batch file, there seems to be no way to use the path to reliably tell whether the path points into a ZIP archive. For example, I put the following batch file, named test.bat, into a ZIP archive:

echo %cmdcmdline%
pause

The output, when run from within the archive, was:

cmd /c ""C:\Users\liana\AppData\Local\Temp\Temp1_test.zip\test.bat" "

Now, it seems likely that Temp1_test.zip is a ZIP archive, not a real directory, but there's no guarantee that it is. Clearly, Windows knows how to tell the difference, so there must be some more reliable way than simply checking whether ".zip" shows up in the path somewhere. But how?

Your program isn't actually being run from "Within" the archive. The archive is first expanded out to a temporary directory (The location for which can vary depending on which archiving tool is being used), before being run.

With this in mind it becomes clear that it isn't ever possible to tell for sure one way or another, so perhaps the best thing to do is instead to check for the presence of the other files you need to run your program, relative to the batch file's location.

Check if another file in the archive exists in the same dir?

if not exist "%~dp0\someotherfile" goto print_please_unzip_ffs_message

%~dp0 is the directory of the bat file (drive and directory of argument zero, which is the bat-file itself)

Why does it fail? I presume you're missing some files because Windows only unzipped the batch file and not the entire archive. If that's true you can check to see if those files exist when the batch file starts.

Or you could distribute your app as a self-extracting zip archive. Doing that would strongly encourage users to run the SFX before running the app. (Although, (for some archivers) an SFX is also a ZIP, so they could rename the SFX to a .zip and then they'd be back to what you have today).

The Windows shell (explorer.exe) associates the .zip extension with the internal zip-folder handler. You can rename anything to .zip and the shell will attempt to treat it as such. The zip-folder handler is a shell extension that, over time, has become fairly integrated into the shell.

The Windows command line environment, which your batch file operates in, has no concept of zipped folders. In that case all you can do is look for the .zip extension.

One thing you can do is distribute your package as an .msi instead, then you won't have these problems.

If you create a batch file named "setup.bat" Windows will silently unzip ALL the files in the zip file to the temp directory instead of prompting the user if they want to do so.

In setup.bat you can then begin with cd /d %~dp0 to change to the currently executing directory. You can then just run your program as normal, or do some sort of installation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM