Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

FileSystemObject is Failing

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

This code is failing using VFP9sp2+ with error code 0x800A004C | CTL_E_PATHNOTFOUND The path is found by the "FolderExists() function. The error occurs on the DeleteFolder() function. I have tried deleting an empty folder and one with content. I have tried adding and removing ending backslashes to the path. No success... The attached screenshot shows the FolderExists is true. I'm stuck...

Code:
lcCompanyPath = Alltrim(company_datapath)
Local lnForm
For lnForm = _Screen.FormCount To 1 Step -1
	If ! Alltrim(_Screen.Forms(m.lnForm).Caption) = 'Company Settings'
		_Screen.Forms(m.lnForm).Release()
	Endif
Endfor

fso = Createobject("Scripting.FileSystemObject")
If fso.FolderExists((lcCompanyPath)) = .T.
	fso.DeleteFolder((lcCompanyPath), .T.)
Endif

Thanks,
Stanley


This screenshot shows everything...

21_fvbtf7.jpg
 
The FileSystemObject DeleteFolder function is stuborn and has never worked as advertised as far as I can remember. However, it can be made to work - try this:

Code:
*!*    Deletes a folder and all of it's contents
FUNCTION DeleteFolder(tcFolderPath AS String) AS Logical
   LOCAL loFSO, llFailed

   loFSO = CREATEOBJECT("Scripting.FileSystemObject")
   llFailed = .T.

   DO WHILE llFailed
      llFailed = .F.

      TRY
          loFSO.DeleteFolder(tcFolderPath, .T.)
          DOEVENTS
      CATCH WHEN .T.
          llFailed = .T.
      ENDTRY
   ENDDO

   DOEVENTS FORCE
   RETURN (NOT DIRECTORY(tcFolderPath))

ENDFUNC

I have tested the above code extensively - it deletes entire folder trees with gigabytes if files in each folder and sub-folder. The VFP DIRECTORY function is solid and can be used instead of FolderExists.
 
hmmm, DOEVENTS FORCE didn't do the trick - RETURN (NOT DIRECTORY(tcFolderPath)) executed before operation completed. This seems to work now (without trailing back slash):

Code:
DECLARE INTEGER Sleep IN kernel32.dll ;
        INTEGER dwMilliseconds

*!*    Deletes a folder and all of it's contents
FUNCTION DeleteFolder(tcFolderPath AS String) AS Logical
   LOCAL loFSO, llFailed

   loFSO = CREATEOBJECT("Scripting.FileSystemObject")
   llFailed = .T.

   DO WHILE llFailed
      llFailed = .F.

      TRY
          loFSO.DeleteFolder(tcFolderPath, .T.)
          DOEVENTS
      CATCH WHEN .T.
          llFailed = .T.
      ENDTRY
   ENDDO

*!*       DOEVENTS FORCE
   Sleep(0)
   RETURN (NOT DIRECTORY(tcFolderPath))

ENDFUNC

For an interesting read, see what 0 does when used in the Sleep function.
 
Hi vernpace,

How is this any different from what I posted, other than the error handler? The functions that actually does the work are exactly the same...

Looks like you are executing it in a loop over and over, ignoring its errors until it magically works???

Thanks, Stanley
 
No, for me it doesn't ever get out of the while loop.

No trailing backslash, not hidden, not write protected, no write protect files, not even a deep hierarchy, simply:
D:\temp\_5P40XKH2T

Generated by sys(2015). And if you suspect that name is causing it, I also tried without underscore.

Only containing a text file, and that is deleted, but not the folder.

When I try to delete the folder in Windows Explorer while the VFP code loops infinitely I get the typical dialog about the operation not possible as long as some process uses a file within. At that point, there is no file anymore, just the empty folder. There really seems something broken in the COM server. The error I get also isn't 0x800A004C | CTL_E_PATHNOTFOUND as stanlyn, but simply Unknown COM status code (0x800A0046).

Googling that error code I see it stands for CTL_E_PERMISSIONDENIED. But permissions can't be a problem, once I kill the VFP process I can delete the folder, VFP created it. But VFP or the OLE class seems to keep some handle, as just ending the loop via ESC key (SET ESCAPE ON) I still can't delete the folder from Windows Explorer, I need to quit VFP.

So fso.DeleteFolder() starts its work, deletes files, but not the folder itself. and since it always errors (even in the first call that obviously works as it deletes files), you never exit the loop, there is some essential problem in fso or fso in conjunction with VFP.

Bye, Olaf.

Olaf Doschke Software Engineering
 
OK, I've integrated the code and is still a total failure and without backslash. Take a look at the screenshot with the wait window. The test folder we are trying to delete is empty... Her is the modified code...

Code:
If llOK = 6
     If Messagebox('Now, do you want to delete everything including images, archives, and all folders ' + ;
	'for company: ' + Alltrim(.txtCompanyID.Value) + ' - ' + Alltrim(.txtCompanyName.Value), 4+16+256, + ;
	'Delete Everything') = 6
lcCompanyPath = Alltrim(company_datapath)
Local lnForm
For lnForm = _Screen.FormCount To 1 Step -1
	If ! Alltrim(_Screen.Forms(m.lnForm).Caption) = 'Company Settings'
		_Screen.Forms(m.lnForm).Release()
	Endif
Endfor

Set Safety Off
lnFailedAttempts = 0

If Directory(lcCompanyPath, 1)
	llFailed = .T.
	fso = Createobject("Scripting.FileSystemObject")

	Do While llFailed
		llFailed = .F.
		Try
			loFSO.DeleteFolder(lcCompanyPath, .T.)
			DoEvents
		Catch When .T.
			llFailed = .T.
			lnFailedAttempts = lnFailedAttempts + 1
			Wait Window 'Failed Attempts: ' + Alltrim(Str(lnFailedAttempts)) Nowait
		Endtry
	Enddo
Endif

Set Safety On
Endif

And here is the screenshot
failed_verdqn.jpg


Thanks, Stanley
 
Alos, vernspace,

before you try some variations and need me to test this, as it only fails for me and not you: This might be something special just like stanlyn has another special problem with this.

I tried some variations myself, doing the DOEVENTS first because as fso.DeleteFolder() triggers the CATCH block the DOEVENTS after it does never run. And in case you loop because of an error you want to do it, so you might begin with it or put it after the endtry, the only line you really try is the DeleteFolder() call anyway. Besides no need to CATCH WHEN .T., you catch aall errors happening without a condition.

The core problem seems specific and can differ for me and stanlyn and none of our errors seems to be your problem. At least there's a system and configuration like yours for which it still works and I can only hope that's the more usual case.

I'm on the latest Win10 Version 10.0.18362 Build 18362, so if you're at another version that might be the essential difference. Then it's no option for me to downgrade anyway. I personally have no problem with it, just trying to reproduce it and find a solution.

Bye, Olaf.

Olaf Doschke Software Engineering
 
I'm on a later build that Olaf. It is Win10Pro64, version 1909, build 18363.592
 
Olaf, the issue could very well be with Windows 10 versions (works fine with Windows 7 and earlier versions of Windows 10)... I will investigate. Thanks for the heads-up. It is important that there is a solution - you would think that Microsoft would have a solid Windows API for this, but there isn't. It is also possible that FSO no longer works properly for Windows 10.

Maybe wrap it in RunAs ???
 
To All,

It appears that VBA's FileSystemObject was broken in Windows 10 1903 Build 18362.295 See here: [link ][/url]

I found another solution (kinda ugly, but it works) by Anatoliy Mogylevets here: [link ][/url]

For me, this is good news - thought I was going crazy...
 
Good finding. It doesn't explain why stanlyn and I had other errors, but likely that's just details of the same problem.

And regarding all other problems people report repeatedly about things file system related like PACK not always working often were solvable by waiting for external events, when it wasn't things like an intervention of antivirus scans. In case of deleting a folder with files, the event that a folder becomes empty could have been the important one.

For myself I have once written a recursive folder deletion, drilling down subfolders first, then deleting files and finally the folder itself. That only fails, when you can't delete some file, but then you also get the detail which file is hindering it.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Hi,
Thanks to everyone confirming I wasn't crazy. To solve my issue, I integrated GriffMG's solution as it is really flexible and can be found here...
Can we expect Microsoft to fix this since it would greatly effects the VB community as well?

Anyway, thanks,
Stanley
 
>likely that's just details of the same problem.

Microsoft owned up to the problem and released a fix; it was a security mitigation against oleaut.dll and from Microsoft reports it ONLY caused issues with empty parameter arrays. They were not aware of any other issues it caused.

>Can we expect Microsoft to fix this

they did. And I cannot replicate the error in non-foxpro - no issue in VB, no issue in Excel or Word VBA

One thing you might want to try is

fso.Getfolder(lCcompanyPath).Delete(.T.)

rather than

fso.DeleteFolder(lcCompanyPath, .T.)
 
The problem with VBA FSO is it (without a brute-force hack) does not realiably support recursive folder deletion which is what my organization needs. Personally, I'm glad Microsoft broke VBA in 1903 because it just forced us to use a Windows API solution which is preferable to VBA. We decided to do the same with two other FSO based functions.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top