这两天在用Excel写一个小工具,就是把给定文件夹下的所有文件里的压缩文件解压,并根据文件名做一定规则的文件删除。
之所以选择Excel,因为这个东西必须在Windows下使用,考虑到Excel的普遍性,而且还可以方便的添加Form来做简单的界面,就选择了它。不过最根本的原因是上次用VS开发Native的Windows程序还是2005年的事情吧。
解压程序开始的时候用的是rar.exe,即标准winrar提供的命令行工具,最后发现.zip的文件不能解压缩(也许是我没找到正确的参数),反正是对rar再也没有爱了。
后来换到7zip,强烈推荐,开源,免费,文件体积小,速度快。
解压是通过Shell函数调用7z.exe,然后就进行类似Dir的操作。
问题是,测试几次后发现每次程序执行的结果都不一样。
多线程?不应该啊,VBA没那么机灵和强大吧。
而且每次断点的时候,结果都趋于正常。
想来想去最后考虑是不是Shell的问题,网上一查果然,这厮调用后立即返回一个PID,后面的VBA代码会立即执行。。。
所以,为了正确使用Shell,必须等它执行结束后才能进行自己程序后面的处理。
网上搜了下发现一篇好文,至少在我测试的XP+Office2004和Windows Server2008+Office2011上没啥问题。
具体方法就是在头部加入API声明:
PrivateDeclareFunctionOpenProcessLib"kernel32"(ByValdwDesiredAccessAsLong,ByValbInheritHandleAsLong,ByValdwProcessIdAsLong)AsLong
PrivateDeclareFunctionCloseHandleLib"kernel32"(ByValhObjectAsLong)AsLong
PrivateDeclareFunctionWaitForSingleObjectLib"kernel32"(ByValhHandleAsLong,ByValdwMillisecondsAsLong)AsLong
然后在需要执行其它命令的地方像下面这样写:
PID = Shell(strRunExe, 1)
IfPID <> 0Then
hProcess = OpenProcess(&H100000,True, PID)
WaitForSingleObject hProcess, -1
CloseHandle hProcess
EndIf
–end–