remove file: care for AntiVir scanning
authorClaus Gittinger <cg@exept.de>
Wed, 16 May 2018 10:45:16 +0200
changeset 22942 776f3c8d88de
parent 22941 37932970b277
child 22943 4cb0b0ada1ff
remove file: care for AntiVir scanning
Win32OperatingSystem.st
--- a/Win32OperatingSystem.st	Tue May 15 20:23:41 2018 +0200
+++ b/Win32OperatingSystem.st	Wed May 16 10:45:16 2018 +0200
@@ -4997,8 +4997,9 @@
     "
 !
 
-removeFile:fullPathName
-    "remove the file named 'fullPathName'; return nil if successful, an OSErrorHolder on errror.
+basicRemoveFile:fullPathName
+    "remove the file named 'fullPathName';
+     return nil if successful, an OSErrorHolder on errror.
      This is a lowLevel entry - use Filename protocol for compatibility."
 
     |error|
@@ -5053,6 +5054,32 @@
     ^ self primitiveFailed
 !
 
+removeFile:fullPathName
+    "redefined to retrying the remove multiple times after some delay.
+     Needed because under windows, an AntiVirus process might be scaning the
+     file currently, and we cannot remove the file while this is ongoing.
+     Q: is there a better way do do this (i.e. figure out why the remove failed)."
+
+    |file retryCtr lastError|
+
+    file := fullPathName asFilename.
+    retryCtr := 10.
+
+    [ file exists ] whileTrue:[
+	lastError := self basicRemoveFile:fullPathName.
+	lastError isNil ifTrue:[^ nil].
+
+	Transcript showCR:('error caught while removing %1: %2'
+			    bindWith:file with:lastError).
+
+	retryCtr := retryCtr - 1.
+	(retryCtr <= 0 or:[file isWritable not]) ifTrue:[
+	    ^ lastError
+	].
+	Delay waitForSeconds:0.1.
+    ].
+!
+
 renameFile:oldPath to:newPath
     "rename the file 'oldPath' to 'newPath'.
      Someone else has to care for the names to be correct and
@@ -5601,15 +5628,15 @@
 %{
     VS_FIXEDFILEINFO *fileInfo;
     UINT uLen;
-    OBJ data;    
-
-    if (__isByteArrayLike(aByteArray) && __isStringLike(which)) {    
-        if (VerQueryValue(__byteArrayVal(aByteArray), __stringVal(which), (LPVOID) &fileInfo, (PUINT) &uLen) == FALSE) {
-            RETURN (nil);
-        }
-        data = __BYTEARRAY_UNINITIALIZED_NEW_INT(uLen);
-        memcpy(__byteArrayVal(data), fileInfo, uLen);   
-        RETURN (data);
+    OBJ data;
+
+    if (__isByteArrayLike(aByteArray) && __isStringLike(which)) {
+	if (VerQueryValue(__byteArrayVal(aByteArray), __stringVal(which), (LPVOID) &fileInfo, (PUINT) &uLen) == FALSE) {
+	    RETURN (nil);
+	}
+	data = __BYTEARRAY_UNINITIALIZED_NEW_INT(uLen);
+	memcpy(__byteArrayVal(data), fileInfo, uLen);
+	RETURN (data);
     }
 badArgument: ;
 %}.
@@ -5621,17 +5648,17 @@
      bytes := self getFileVersionInfoOf:'./stx.exe'.
      self extractVersionValue:'\' from:bytes.
      vfi := self extractVersionValue:'\VarFileInfo\Translation' from:bytes.
-     lang := vfi unsignedInt16At:1.    
+     lang := vfi unsignedInt16At:1.
      codePage := vfi unsignedInt16At:3.
-     assocs := #( 'CompanyName' 'FileDescription' 'FileVersion' 'ProductName') collect:[:each |    
-        sfi := self extractVersionValue:('\StringFileInfo\%1%2\%3' 
-                                        bindWith:(lang hexPrintString:4) 
-                                        with:(codePage hexPrintString:4)
-                                        with:each) 
-                 from:bytes.
-        each -> (sfi zeroByteStringAt:1 maximumSize:999)
+     assocs := #( 'CompanyName' 'FileDescription' 'FileVersion' 'ProductName') collect:[:each |
+	sfi := self extractVersionValue:('\StringFileInfo\%1%2\%3'
+					bindWith:(lang hexPrintString:4)
+					with:(codePage hexPrintString:4)
+					with:each)
+		 from:bytes.
+	each -> (sfi zeroByteStringAt:1 maximumSize:999)
      ].
-     Dictionary withAssociations:assocs    
+     Dictionary withAssociations:assocs
     "
 
     "Created: / 23-04-2018 / 10:08:04 / Maren"
@@ -5934,17 +5961,17 @@
     bytes := self getFileVersionInfoOf:(filename asFilename pathName).
     self extractVersionValue:'\' from:bytes.
     vfi := self extractVersionValue:'\VarFileInfo\Translation' from:bytes.
-    lang := vfi unsignedInt16At:1.    
+    lang := vfi unsignedInt16At:1.
     codePage := vfi unsignedInt16At:3.
-    assocs := infoKeys collect:[:each |    
-       sfi := self extractVersionValue:('\StringFileInfo\%1%2\%3' 
-                                       bindWith:(lang hexPrintString:4) 
-                                       with:(codePage hexPrintString:4)
-                                       with:each) 
-                from:bytes.
+    assocs := infoKeys collect:[:each |
+       sfi := self extractVersionValue:('\StringFileInfo\%1%2\%3'
+				       bindWith:(lang hexPrintString:4)
+				       with:(codePage hexPrintString:4)
+				       with:each)
+		from:bytes.
        each -> (sfi zeroByteStringAt:1 maximumSize:999)
     ].
-    ^ Dictionary withAssociations:assocs    
+    ^ Dictionary withAssociations:assocs
 
     "
      self getFileInfos:#('CompanyName' 'FileDescription' 'ProductVersion') fromFile:'./stx.exe'
@@ -5964,24 +5991,24 @@
     DWORD dummy;
 
     if (__isStringLike(aPathName)) {
-        sz = GetFileVersionInfoSizeA(__stringVal(aPathName), &dummy);
+	sz = GetFileVersionInfoSizeA(__stringVal(aPathName), &dummy);
     } else if (__isUnicode16String(aPathName)) {
-        sz = GetFileVersionInfoSizeW(__unicode16StringVal(aPathName), &dummy);
+	sz = GetFileVersionInfoSizeW(__unicode16StringVal(aPathName), &dummy);
     } else {
-        goto badArgument;
+	goto badArgument;
     }
 
     if (sz > 0) {
-        OBJ versionData;
-
-        versionData = __BYTEARRAY_UNINITIALIZED_NEW_INT(sz);
-        if (versionData == nil) {
-            RETURN (nil);
-        }
-        if (GetFileVersionInfo(__stringVal(aPathName), 0, sz, __ByteArrayInstPtr(versionData)->ba_element) == FALSE) {
-            RETURN (nil);
-        }
-        RETURN (versionData);
+	OBJ versionData;
+
+	versionData = __BYTEARRAY_UNINITIALIZED_NEW_INT(sz);
+	if (versionData == nil) {
+	    RETURN (nil);
+	}
+	if (GetFileVersionInfo(__stringVal(aPathName), 0, sz, __ByteArrayInstPtr(versionData)->ba_element) == FALSE) {
+	    RETURN (nil);
+	}
+	RETURN (versionData);
     }
     RETURN (nil);
 badArgument: ;