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 TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

"File Access is denied" on a TMP file from COM DLL?

Status
Not open for further replies.

LlomaxX

Programmer
Nov 7, 2002
64
US
I have created a Foxpro COM dll that I am calling from a Visual Basic 6.0 COM object. The VB object is created multiple times, each instance running in its own thread, managed by an in-house task manager. Each object is supposed to perform its task on different sets of data.

When two or more of my VB objects are running simultaneously, I will get "nError: 1705 Message(): File access is denied." The file that I cannot access is usually something like "..\TEMP\FP8C000D.TMP" The line it is telling me the error is occuring on is trying to do a simple select into a cursor.

Why can't I do a select into a cursor from more than one process? If two instances of a Foxpro com object try to create a cursor with the same name, do the temp files collide? That doesn't seem very likely to me.

By the way, I created this DLL as a multi-threaded COM Server (dll), and I get the error I stated above. If I build it as a single-threaded COM server, then I get an error 2031: User-interface operation not allowed at this time. It happens on the exact same line, so I suspect the user interface operation it's trying to perform is a dialog box telling me that file access is denied.

I'm kinda stumped. What am I doing wrong, and is there any way to fix this so that multiple tasks can run side by side without stepping on each other?
 
If the processes are creating cursors at the same time, it's very likely they would try to create them with the same name since the somewhat random (notice I didn't say unique) file names are based on the system clock.
You should probably generate a unique file name prior to running the cursor using somethin like:
Code:
STORE "tmp" + SubStr(SYS(2015), 3) TO cCursor
SELECT .... FROM ....;
   INTO CURSOR (cCursor)

"tmp" prepended to the name ensures that you won't have a file (cursor) name starting with a number, which Fox would translate to something like "a" or "b" for a work area.



-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Well, I tried something similar...Remember I said each object was supposed to operate on different sets of data? I thought maybe it was because my cursors all had the same name, so I changed from "select .... into cursor hold" to "select . . . . into cursor (this.JobNumber + 'hold')"

Now, those job numbers are all very similar, but unique. they all start with the a date in yyyymmdd format, then a unique 4 digit number. Is that why I'm getting conflicts, because they are trying to create TMP files with the same names?
 
I should have mentioned in the last post that I tried the similar approach, "and it didn't work"

Also, the error messages give me the name of the file it is having the conflict with, and those files don't even exist. I even try waiting a few minutes, letting the first one run for a while before firing off the second one with the same results. It will not run as long as another VB object is still running...

Maybe I should destroy the Foxpro object the minute I am done with it . . . they wouldn't be able to start at the same time, but maybe they could still run simultaneously eventually....I am keeping that object around alot longer than I need to
 
That seemed to help quite a bit

Before when I tried it, 4 tasks were created simultaneously, and only one would run. The other three would error out, wait 60 seconds, and try again, and still error out.

After I made the change, 4 tasks were created simultaneously, and only one errored out right away. A second one fell off and errored out a few seconds later, but two ran side by side, and 60 seconds later, the other two could run with no problem.

But I would still like to know what is causing this problem and avoid it all together. When this thing runs in production, there could be a mulititude of these things all running at the same time, and if it takes too many tries before some of them can run, they will time out and never run, and then we'll have problems.

How can I avoid getting the File access is denied error altogether?

 
Is there any way to use the TMPFILES command from inside my class object? I hand a working folder path to my object to create temporary tables and such. If the TMP files Foxpro is creating were in different locations for each instance of the class object, then maybe they wouldn't be fighting over the TMP files.

Everything in the help documentation says I can set the path in a configuration file, but I'm not using a configuration file. My class does set alot of datasession properties, like SET TALK OFF and SET EXCLUSIVE OFF when the base class loads. Can I set the TMPFILES location after the class has loaded and the property for the Working Folder path has been set?
 
yyyymmdd format, then a unique 4 digit number
If the cursor (or table for that matter) begins with a number, VFP will assign it an alias of a-l.
If I understand your methodology correctly, the COM server is what is creating the cursor, therefore, I think that if your cursor is created using this.JobNumber + 'hold', you could end up with something like '123hold', which begins with a number.
Have you tried something like 'hold' + this.JobNumber?

...those files don't even exist.
They probably exist as ????????.tmp somewhere as a temp file created by the COM server. And not necessarily with the file name you specify.

Can I set the TMPFILES location after the class has loaded and the property for the Working Folder path has been set?
TMPFILES can only be set as a configuration item on startup. You would have to specify a path for each output file somewhere in your class.
Again, if I understand correctly, since the COM server is creating the cursors, not the VB objects, you have to ensure each one is unique to the COM server and not just the client.
You may need to create them as tables nstead of cursors and clean them up (delete them) after they have been processed/sent to the VB client.


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top