如何检测是否从ZIP存档运行Windows批处理文件
我们的应用程序在Windows上分布的一种方式是作为ZIP存档。在这个档案里面有一个用于启动应用程序的批处理文件。用户应该在运行我们的应用程序之前解压缩存档,但是经常用户忽略我们的说明并尝试运行应用程序而不先解压缩存档。当用户这样做时,应用程序无法启动,但对用户不明显是什么引起了失败。我们希望从批处理文件中检测它是否从ZIP存档内运行,如果是,请向用户显示一条消息,提醒他先解压缩存档。如何检测是否从ZIP存档运行Windows批处理文件
但是,我不清楚如何检测这种情况。尽管批处理变量%cmdcmdline%
包含运行批处理文件的命令,但似乎无法使用该路径可靠地判断路径是否指向ZIP归档文件。例如,我把下面的批处理文件,命名为test.bat的,成ZIP档案:
echo %cmdcmdline% pause
的输出,从归档中运行时,是:现在
cmd /c ""C:\Users\liana\AppData\Local\Temp\Temp1_test.zip\test.bat" "
,似乎可能 Temp1_test.zip是一个ZIP压缩文件,而不是一个真实的目录,但不能保证它是。显然,Windows知道如何区分差异,因此必须比简单地检查“.zip”是否显示在某个路径中更可靠。但是如何?
您的程序实际上并未从存档的“内部”运行。在运行之前,档案首先扩展到一个临时目录(根据使用的归档工具的不同而不同)。
考虑到这一点,很明显无法确定这种或那种方式,所以最好的办法是检查是否存在需要运行的其他文件程序,相对于批处理文件的位置。
为什么会失败?我推测你错过了一些文件,因为Windows只解压了批处理文件而不是整个压缩文件。如果这是真的,你可以检查批处理文件启动时是否存在这些文件。
Windows shell(explorer.exe)将.zip扩展名与内部zip文件夹处理程序相关联。您可以将任何内容重命名为.zip,并且外壳程序将尝试按照这种方式对待它。 zip文件夹处理程序是一个shell扩展,随着时间的推移,它已经相当集成到了shell中。
批处理文件在其中运行的Windows命令行环境没有压缩文件夹的概念。在这种情况下,您只能查找.zip扩展名。
你可以做的一件事是将你的软件包作为.msi代替,然后你就不会有这些问题。
在这种特殊情况下,作为.msi分发并不好,因为ZIP归档文件旨在成为我们的“通用”软件包。 (还有一个用于在ZIP存档中启动应用程序的shell脚本。) – uckelman 2009-11-01 19:10:07
如果您创建一个名为批处理文件“的setup.bat”的Windows将静静地将zip文件中的所有文件解压缩到临时目录,而不是在用户想要的情况下提示用户。
在设置中。然后,您可以从cd /d %~dp0
开始更改为当前正在执行的目录。然后你可以像平常那样运行你的程序,或者进行某种安装。
或者您可以将您的应用作为自解压缩zip文件分发。这样做会强烈鼓励用户在运行应用程序之前运行SFX。 (虽然(对于某些存档)SFX也是ZIP,所以他们可以将SFX重命名为.zip,然后他们会回到你今天的样子)。
我们已经发布了Windows安装程序。 ZIP档案适用于以下人员:(1)不能在他们正在使用的(Windows)系统上安装,或者(2)使用Windows,Mac OS X或Linux以外的某些操作系统,我们也提供包。作为SFX分发可能会阻止档案服务于第2个目的。 – uckelman 2009-11-02 10:10:25
@uckelman,SFX ZIP仍然是一个完全合法且格式兼容的ZIP文件,所以它很可能在其他平台上可用。但是,除了构建提取存根的平台之外,其他位置不会自行提取。 – RBerteig 2010-10-19 01:13:38
@RBerteig - 小心! SFX ZIP没有“规格”。因此,每个zip工具或库可能会以不同的方式构建SFX。一些压缩工具可以创建不是真正的zip文件的自定义SFX文件。 WinZip和DotNetZip是您的声明是正确的两个:SFX是一个ZIP。 – Cheeso 2010-10-24 14:49:43
啊哈!我没有意识到,我在我的例子中看到的是一个真正的道路,而不是Windows shell发明的一些创造。我想我可以简单地测试我们其他文件的存在,如果批处理文件是从归档文件运行的,那么它肯定不会存在于临时目录中。 – uckelman 2009-11-01 19:13:55
不,检查另一个文件的存在将不起作用。 WinRAR在尝试运行时将整个存档提取到临时目录,以便该文件将在那里。我没有对它进行测试,但是我发现很可能大多数其他归档程序都是这样做的,因为它提高了正确打开文件的可能性(对档案中其他文件的依赖性)。 – 2009-11-01 19:23:26
但是,如果所有文件都被提取,那么应用程序就不会有问题 - 所以在这种情况下,我们不会提醒用户。这只是部分提取发生的状态,存在问题。 – uckelman 2009-11-01 19:28:25