I would like to know if it is possible to nest a dataset within a dataset and then nest this data set with in another dataset. Therfore 3 levels of nesting. Currently I only manage to nest one dataset with in the other. When attemting to nest the third level the database manages to run successfully the first time I compile my program and I am able to enter data. When I then attempt to run the program the second time I an execption raised by EDBClient with message "mismatch in datapacket".
So I would like to know is it possible to nest 3 levels of datasets within each other?
Kind regards
Riaan
Short story:
Try it with Delphi XE... for my nowadays main project this resolved the bug.
Long story:
I faced the same problem you have with 3 or more levels of nested datasets when there's any error on the database side with Delphi 2010.
The previous last version I heavily used was Delphi 2007 without problems, so there's a chance the bad behavior was introduced in Delphi 2009 or Delphi 2010.
I traced this problem down to midas.dll on the client side, and it happens no matter if you're linking midas statically using MidasLib. Midas "thinks" the packet it receives from the server is malformed, and raises the exception. This exception breaks the "normal" error reconcile process, so there's no way to try to recover from an error: OnReconcileError never fired and the process is aborted due to the lack of try/except blocks inside this part of the VCL.
I'm sure it was a bug, but not if it happens on the server or on the client side, When I was working to produce a project to put a support ticket, while trying to reduce it to the minimum possible, it happens Delphi XE was released and I'm under SA, so I get it the last minute.
Download, Install, configure... then, I compiled my to support project and everything worked fine. I compiled my main project: the one where I was facing real problems with the users because of this and the fact I use to raise exceptions in database triggers and stored procedures due to last second validations or state/condition changes. Everything worked fine. The user is receiving meaningful error messages and the application recovered his ability to perform data-transformations and retries on the fly, or to ask the user what to do in some circumstances.
Sorry, I found no workaround during my efforts to diagnose and report this problem to Embarcadero, maybe someone else can help you better without suggesting to upgrade.
Simple answer is yes, you can have three levels of datasets nested within each other. I have examples of ClientDataSets where the nesting goes down 6 levels. In fact, I do not think there is a limit to the depth of nesting, other than that imposed by memory constraints.
Related
Updates
2016-02-18: Added process information
I have a Delphi program compiled using XE4. It is being used by a few hundred customers. A couple of weeks ago one of these customers reported that some areas of the executable was being erased (images bellow) randomly during the day. This client has 35 sites using this exe and the problem occurs on no more than 10 of these sites.
Investigation
1 - My first suspicion was an infinite loop. The exe keeps responding while the components are erased, nothing changed on the code so radically from the time this problem did'n happen and the logs don't show any loop (this exe has logs everywhere).
2 - Misbehaving threads. I have a separate thread that syncs data between this exe and our server in the cloud. Again, logs don't show that the thread is running when the problem occur and again, nothing was changed here.
3 - Some other program (antivirus?) is affecting my exe. Couldn't investigate this hipotesis properly yet, but until now couldn't find any installed program that raised my attention.
My question is: What could be causing this issue? How can I investigate further? I know this may be a wide question but this is all information I could gather and I can't imagine many more places to look at.
Images
1 - In the image bellow the red-stroked area should be a TToolBar
2 - In this second image there are three areas, from the top to the bottom the first one should be a TToolBar, the second one should be the title of the child form and the third one should be a TwwDBGrid
3 - The third example shows on the top the erased area where should be a TEdit, just bellow it there's what should be a line on a TwwDBGrid and on the side we can see an erased scrollbar from the TwwDBGrid
4 - This last example shows 5 erased areas: The title of the application, the main TToolBar, The title of the Form, a TButton and two TwwDBGrid
5 - This is an interesting example beacause beyond the erased components there are 4 TSpeedButtons that are not erased but they are without the images they have originally (the first red stroked areas). The other 3 red stroked areas are, in order, 2 TEdits, a TwwDBGrd and a TButton
Process Information
I got a screenshot by the momment the problem occurs. scgolr is my software.
There is really not enough detailed information to give you a definite answer. However, I can answer with some directions on your question:
How can I investigate further?
Because of what you have stated:
The program is in use by a few hundred customers
One (only) customer experiences the problem
First occurance of the problem was some weeks ago
the first thing to do, is get in contact with the customer, and get the information you say that you have asked for but not got. The questions that need to be answered are:
What has changed in the customers environment at the time the problem
started with respect to hardware, network, server, OS, other software
running in the PCs?
Has anything changed in the way your customer is using your software?
What do the customer have to do to get rid of the problem, once it occurs? Close the program? Restart the PC? Or maybe just minimize - restore the erroneous window?
With the above I do not suggest that the fault is with this one customer and their equipment or their way of using the software. It may just be that the combination at the site which is different from all your other customers, triggers the problem to show up.
Some specific things to check in your software and at the site when problem occurs and if the problem goes away with a minimize - restore of the application (which would suggest a painting interrupted problem:
Do you call Application.ProcessMessages at any time?
Does the background thread access same data as the GUI? If yes, are the data protection properly in place (locking, synchronisation).
Does the background thread access any GUI components without Synchronize?
Finally I suggest that you visit the customer onsite. You get much better and faster answers in a direct discussion.
Edit after process information received.
There is nothing alarming concerning GDI or User objects. But it is alarming when you say in the comments that you call Application.ProcessMessages in many places, obviously to 'fix' a non-responsive UI. For example, what happens if the user double clicks a button, but does it slowly enough that Windows detects it as to separate clicks? First click may start your long lasting procedure within which you call A.P. The second click is read from the message que which starts the same procedure. Now the second call to the procedure runs (with its own calls to A.P.) and eventually ends and execution returns to the first call. Depending on what you do in this procedure, you may well be messing up handles and device contexts etc. A strong recommendation said with a friendly intent: Get rid of those calls to A.P.
the problem is with the security plugin (Warsaw - Gas Tecnologia) bank's website that your client is accessing , update it and it will be solved , the problem happens in Brazil
As #SebastianZ and #AlekseyK pointed out you may experiment exaustin of some GDI resource (handles?).
If the system coukd be accessed some tools like Process explerer or process hacker could give you some hints. This utility may help too GDIView
I don't know if this may apply to your case, but sometimes database data corruption can lead to strange effect in running programs (i remember 'Data Bombs' causing out of memory exceptions ...
So if something cause a GDI allocation loop, the graphics of your app cauld be affected in 'strange' ways
I am getting this AV message about 3 to 5 seconds after the applications close as expected:
Exception EAccessViolation in module rtl160.bpl at 00073225. Access violation at address 500A3225 in module 'rtl160.bpl'. Read of address 00000004.
These (20) applications are very similar in that they are IBX business applications. About half of them did not cause the AV to occur.
These applications were ported from Delphi-xe and they worked flawlessly for a long time. No changes were made to the projects in the port. Both 32 and 64 bit builds gave the same results.
Is this a bug in some library's finalization section freeing a resource or something?
I am using Delphi-XE2 Update 3.
Would appreciate the help.
Try using madExcept / EurekaLog etc. - they give you detailed stack trace on AV. This is not always a panacea, but can point you to the problem.
Access Violations are by their nature already very troublesome beasts since they deal with invalid pointers in memory. One that occurs a while after an application shuts down is even worse because that's when your app is in "cleanup" mode. You're could be dealing with something that went wrong much earlier in the application, but is only exposing itself at shutdown.
General Tips:
Try to always undo things in the reverse order you did them. E.g.
Create A, Create B ... Destroy B, Destroy A
Connect to Database, Open Dataset ... Close Dataset, Disconnect from Database
Even making sure you've done all the above before shutting down can help tremendously.
Any threads that are still running while your application is running can cause problems.
Preferably ensure all your child threads are properly terminated before final shutdown.
Refer back to Closing datasets above. Depending on what you're doing, some database components will create their own threads.
If you're using COM, try ensure ComObj is high up in the initialization sequence (I.e. place it as high as possible in your DPR).
Delphi finalizes units in the reverse order that they were initialized.
And you don't want ComObj to finalize before other things that are dependent on ComObj have also done so.
If you're using interface references, make sure you resolve circular reference issues.
Some of these problems can be tricky to find, but you can do the following:
Setup a source-code "sandbox" environment (you're going to chuck all your changes as soon as you've found the problem).
Figure out the simplest set of steps required to guarantee the error. (Start app and immediately shutdown would be ideal.)
Then you're going to comment-out delete wipe out chunks of code between tests and basically follow a divide and conquer approach to:
rip out code
test
if the problem persists, repeat. Else roll-back and rip out a different chunk of code.
eventually your code base will be small enough to pinpoint likely problems which can be tackled with targeted testing.
I've had this kind of access violation problem on occasion with old Delphi or C++Builder projects. Today I had it with C++Builder. At the time of the crash, by looking in the Debug -> Call Stack window, I can see that it's happening inside a call to fflush, called by __exit_streams and _exit.
I'm not sure what is causing it, since it's so deep in the Borland library code, but it seems to come and go at random when the code changes. And it seems to be more common with multi-form applications.
This time the error went away when I just added a new button on the main form. A button which is just there, has no event handlers and does not do anything. I think that any random change to the code, classes, variables etc rearranges the memory layout when you relink the application, and that either triggers or untriggers the error.
For now, I just leave the new button on the form, set it to "not visible" so that there's no visible change. As it seems to work, it's good enough solution for me at this time.
This has happened to me on more than one occasion and has led to many lost hours chasing a ghost. As typical, when I am debugging some really difficult timing-related code I start adding tons of OutputDebugString() calls, so I can get a good picture of the sequence of related operations. The problem is, the Delphi 6 IDE seems to be able to only handle that situation for so long. I'll use a concrete example I just went through to avoid generalities (as much as possible).
I spent several days debugging my inter-thread semaphore locking code along with my DirectShow timestamp calculation code that was causing some deeply frustrating problems. After having eliminated every bug I could think of, I still was having a problem with Skype, which my application sends audio to.
After about 10 seconds the delay between my talking and hearing my voice come out of Skype on the second PC that I was using for testing, the far end of the call, started to grow. At around 20 - 30 seconds the delay started to grow exponentially and at that point triggered code I have that checks to see if a critical section was being held too long.
Fortunately it wasn't too late at night and having been through this before, I decided to stop relentlessly tracing and turned off the majority of the OutputDebugString(). Thankfully I had most of them wrapped in a conditional compiler define so it was easy to do. The instant I did this the problems went away, and it turned out my code was working fine.
So it looks like the Delphi 6 IDE starts to really bog down when the amount of OutputDebugstring() traffic is above some threshold. Perhaps it's just the task of adding strings to the Event Log debugger pane, which holds all the OutputDebugString() reports. I don't know, but I have seen similar problems in my applications when a TMemo or similar control starts to contain too many strings.
What have those of you out there done to prevent this? Is there a way of clearing the Event Log via some method call or at least a way of limiting its size? Also, what techniques do you use via conditional defines, IDE plug-ins, or whatever, to cope with this situation?
A similar problem happened to me before with Delphi 2007. Disable event viewing in the IDE and instead use DebugView from Sysinternals.
I hardly ever use OutputDebugString. I find it hard to analyze the output in the IDE and it takes extra effort to keep several sets of multiple runs.
I really prefer a good logging component suite (CodeSite, SmartInspect) and usually log to various files. Standard files for example are "General", "Debug" (standard debug info that I want to collect from a client installation as well), "Configuration", "Services", "Clients". These are all set up to "overflow" to a set of numbered files, which allows you to keep the logs of several runs by simply allowing more numbered files. Comparing log info from different runs becomes a whole lot easier that way.
In the situation you describe I would add debug statements that log to a separate logfile. For example "Trace". The code to make "Trace" available is between conditional defines. That makes turning it on pretty simple.
To avoid leaving in these extra debug statements, I tend to make the changes to turn on the "Trace" log without checking it out from source control. That way, the compiler of the build server will throw out "identifier not defined" errors on any statements unintentionally left in. If I want to keep these extra statements I either change them to go to the "Debug" log, or put them between conditional defines.
The first thing I would do is make certain that the problem is what you think it is. It has been a long time since I've used Delphi, so I'm not sure about the IDE limitations, but I'm a bit skeptical that the event log will start bogging down exponentially over time with the same number of debug strings being written in a period of 20-30 seconds. It seems more likely that the number of debug strings being written is increasing over time for some reason, which could indicate a bug in your application control flow that is just not as obvious with the logging disabled.
To be sure I would try writing a simple application that just runs in a loop writing out debug strings in chunks of 100 or so, and start recording the time it takes for each chunk, and see if the time starts to increase as significantly over a 20-30 second timespan.
If you do verify that this is the problem - or even if it's not - then I would recommend using some type of logging library instead. OutputDebugString really loses it's effectiveness when you use it for massive log dumps like that. Even if you do find a way to reset or limit the output window, you'd be losing all of that logging data.
IDE Fix Pack has an optimisation to improve performance of OutputDebugString
The IDE’s Debug Log View also got an optimization. The debugger now
updates the Log View only when the IDE is idle. This allows the IDE to
stay responsive when hundreds of OutputDebugString messages or other
debug messages are written to the Debug Log View.
Note that this only runs on Delphi 2007 and above.
Imagine i want to parse a binary blob of data. If all comes okay, then all the logs are INFO, and user by default does not even see them. If there is an error, then user is presented with error and can view the log to see exact reason (i don't like programs that just say "file is invaid. for some reason. you do not want to know it" )
Probably most log libraries are aimed at quickly loading, classifying and keeping many many log lines per second. which by itself is questionable, as there is no comfort lazy evaluation and closures in Delphi. Envy Scala :-)
However that need every line be pre-сlassified.
Imagine this hypothetical flow:
Got object FOO [ok]
1.1. found property BAR [ok]
1.1.1. parsed data for BAR [ok]
1.2 found property BAZ [ok]
1.2.1 successfully parsed data for BAR [ok]
1.2.2 matching data: checked dependancy between BAR and BAZ [fail]
...
So, what can be desired features?
1) Nested logging (indenting, subordination) is desired then.
Something like highlighted in TraceTool - see TraceNode.Send Method at http://www.codeproject.com/KB/trace/tracetool.aspx#premain0
2) The 1, 1.1, 1.1.1, 1.2, 1.2.1 lines are sent as they happen in a info sink (TMemo, OutputDebugString, EventLog and so one), so user can see and report at least which steps are complete before error.
3) 1, 1.2, 1.2.2 are retroactively marked as error (or warning, or whatever) inheriting from most specific line. Obviously, warning superseeds info, error superseeds warning and info, etc/
4) 1 + 1.2 + 1.2.2 can be easily combined like with LogMessage('1.2.2').FullText to be shown to user or converted to Exception, to carry the full story to human.
4.1) Optionally, with relevant setup, it would not only be converted to Exception, but the latter even would be auto-raised. This probably would require some kind of context with supplied exception class or supplied exception constructing callback.
5) Multisink: info can be just appended into collapsible panel with TMemo on main form or currently active form. The error state could open such panel additionally or prompt user to do it. At the same time some file or network server could for example receive warning and error grade messages and not receive info grade ones.
6) extra associated data might be nice too. Say, if to render it with TreeView rather than TMemo, then it could have "1.1.1. parsed data for BAR [ok]" item, with mouse tooltip like "Foo's dimensions are told to be 2x4x3.2 metres"
Being free library is nice, especially free with sources. Sometimes track and fix the bug relying solely on DCUs is much harder.
Non-requiring extra executable. it could offer extra more advanced viewer, but should not be required for just any functionality.
Not being stalled/abandoned.
ability to work and show at least something before GUI is initialized would be nice too. Class constructors are cool, yet are executed as part of unit visualization, when VCL is not booted yet. If any assertion/exception is thrown from there, user would only see Runtime error 217, with all the detail lost. At least OutputDebugStreen can be used, if nothing more...
Stack tracing is not required, if needed i can do it and add with Jedi CodeLib. But it is rarely needed.
External configuration is not required. It might be good for big application to reconfigure on the fly, but to me simplicity is much more important and configuration in code, by calling constructors or such, is what really matters. Extra XML file, like for Log4J, would only make things more fragile and complex.
I glanced few mentioned here libraries.
TraceTool has a great presentation, link is above. Yet it has no info grade, only 3 predefined grades (Debug/Error/Warning) and nothing more, but maybe Debug would suit for Info replacement... Seems like black box, only saving data into its own file, and using external tool to view it, not giving stream of events back to me. But their messages nesting and call chaining seems cool. Cools is also attaching objects/collection to messages.
Log4D and Log4Delphi seems to be in a stasis, with last releases of 2007 and 2009, last targeted version Delphi 7. Lack documentation (probably okay for log4j guy, but not for me :- ) Log4Delphi even had test folder - but those test do not compile in Delphi XE2-Upd1. Pity: In another thread here Log4delphi been hailed for how simple is to create custom log appender (sink)...
BTW, the very fact that the only LOG4J was forked into two independent Delphi ports leaves the question of which is better and that both lack something, if they had to remain in split.
mORMot part is hardly separated from the rest library. Demo application required UAC escalation for use its embedded SQLite3 engine and is frozen (no window opened, yet the process never exits normally) if refused Admin grants. Another demo just started infinite stream of AV exceptions, trying to unwind the stack. So is probably not ready yet for last Delphi. Though its list of message grades is excessive, maybe even a bit too many.
Thank you.
mORMot is stable, even with latest XE2 version of Delphi.
What you tried starting were the regression tests. Among its 6,000,000 tests, it includes the HTTP/1.1 Client-Server part of the ORM. Without the Admin rights, the http.sys Server is not able to register the URI, so you got errors. Which makes perfectly sense. It's a Vista/Seven restriction, not a mORMot restriction.
The logging part can be used completely separated from the ORM part. Logging is implemented in SynCommons.pas (and SynLZ.pas for the fast compression algorithm used for archival and .map embedding). I use the TSynLog class without any problem to log existing applications (even Delphi 5 and Delphi 6 applications), existing for years. The SQLite3 / ORM classes are implemented in other units.
It supports the nesting of events, with auto-leave feature, just as you expect. That is you can write:
procedure TMyClass.MyMethod(const Params: integer);
begin
TSynLog.Enter;
// .... my method code
end;
And adding this TSynLog.Enter will be logged with indentation corresponding to the recursive level. IMHO this may meet your requirements. It will declare an ISynLog interface on the stack, which will be freed by Delphi at the "end;" code line, so it will implement an Auto-Leave feature. And the exact unit name, method name and source code line number will be written into the log (as MyUnit.TMyClass.MyMethod (123)), if you generated a .map file at compilation (which may be compressed and appended to the .exe so that your customers logs will contain the source line numbers). You have methods at the ISynLog interface level to add some custom logging, including parameters and custom state (you can log objects properties as JSON if you need to, or write your custom logging data).
The exact timing of each methods are tracked, so you are able to profile your application from the data supplied by your customer.
If you think the logs are too much verbose, you have several levels of logging, to be customized on the client side. See the blog articles and the corresponding part of the framework documentation (in the SynCommons part). You've for instance "Fail" events and some custom kind of events. And it is totally VCL-independent, so you can use it without GUI or before any GUI is started.
You have at hand a log viewer, which allow client-side profiling and nested Enter/Leave view (if you click on the "Leave" line, you'll go back to the corresponding "Enter", e.g.):
If this log viewer is not enough, you have its source code to make it fulfill your requirements, and all the needed classes to parse and process the .log file on your own, if you wish. Logs are textual by default, but can be compressed into binary on request, to save disk space (the log viewer is able to read those compressed binary files). Stack tracing and exception interception are both implemented, and can be activated on request.
You could easily add a numeration like "1.2.1" to the logs, if you wish to. You've got the whole source code of the logging unit. Feel free to ask any question in our forum.
Log4D supports nested diagnostic contexts in the TLogNDC class, they can be used to group together all steps which are related to one compound action (instead of a 'session' based grouping of log events). Multi-Sinks are called Appenders in log4d and log4delphi so you could write a TLogMemoAppender with around twentyfive lines of code, and use it at the same time as a ODSAppender, a RollingFileAppender, or a SocketAppender, configurable at run time (no external config file required).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have a piece of code that is trying to write to disk many files in one second. However, it fails wince I have installed Kaspersky Anrivirus 2011.
Stream:= TFileStream.Create(sName, fmCreate);
The code totally worked with Kaspersky 2010 and also works with Kaspersky 2011 if I disable its scanners (it cannot be totally unloaded from memory - unless it is uninstalled). The code also works if (Kaspersky 2011 is running and) I write to disk slooooowly. So it obviously is not fast enough to handle my disk requests.
The error I get is EFCreateError ('Cannot create xxx file blablabla'). Error is random. Most of the files are written to disk. About 10% fail.
I have tried to get support but is impossible to find a real person at Kaspersky to speak with. Their so called 'support' is actually a FAQ data base. Of course it speaks about how to install the product and related stuff. There is nothing about programing-related issues. Any ideas?
PS: this has repercussions for the entire Delphi community! All our customers will fail to use Delphi software if they are using KIS 2011 as antivirus. For the moment I recommend to my users to disable their antivirus but I need a real solution.
It will be nice if a person with KIS 2011 can confirm the problem. Just create a tiny program that write 200 small files to disk using TFileStream.
UPDATE:
The problem appears ONLY when the file does not exist and it is created (created as opposed to overwritten).
Similar report: https://forums.embarcadero.com/thread.jspa?threadID=32751&tstart=15
Similar report: http://forum.kaspersky.com/index.php?showtopic=120561
A possible solution that popped in my mind is to detect if KIS is running and if it is, to put a delay after each writing to disk. Or at leat, let the user know there may be problems. Anybody knows how to detect if a service is running?
I added a delay of 650ms (after each file creation) and the bug is still there). So is not about how fast you write to disk but about how many files you write.
Just uninstalled KIS 2011. The problem does not appear anymore.
Just reinstalled the good old KIS 2010. The bug is still there but it appear rarely (about every 300 files instead of about 30 as in KIS 2011).
The problem was confirmed on a second computer.
NEWS: The crash appears in TFileStream.Create however it may be caused by a function called earlier: TestWriteAccess. If I disable this function, the TFileStream.Create doesn't fail anymore. Well, this doesn't change things too much. No matter which line of code generates the error, the program still fails (randomly) to write files to disk while Kaspersky is running.
Still waiting a response from a real person from Kaspersky...
More automated responses received from Kaspersky support (I sent emails to support in several countries). All pointing to a FAQ database.
I change my status from Kaspersky fan (and customer) to Kaspersky hater because I finally receive an answer from a real person from Kaspersky support and it was plain and simple obnoxious.
To test the code, try to use the code in a loop, to create 1000 files. The program creates a bunch of files (random number) then it fails at StreamFile:= TFileStream.Create.
Update: The issue can be fixed by entering a small delay after creating each file.
https://docs.google.com/forms/d/1H3_O1z1iEqfh9ZT9u3B0R1tGEj-Hc9o7rAE0LKPr33Y
2013 Update
Starting with this afternoon (after an update) KIS conflicts with Delphi.
Every time I compile a project KIS spikes to 100% CPU utilization. I will have to uninstall it.
2017 Update
All false positive alarms disappeared magically for all my Delphi programs starting with 2017. It seems that it was enough for a program like Kaspersky remove Delphi-generated executables from its virus list; all other smaller antivirus programs followed.
Delphi 7, Win 7 (32), KIS 2011
You need to instruct your users, i.e. Kaspersky's customers, that Kaspersky is interfering with the operation of your software, and that THEY should report it. Express your frustration that you, as a developer, don't have access to a real human being. This is the only way that the anti-malware companies will ever react - bad PR with their paying customers.
Kaspersky = pirate company? Maybe yes, maybe no. Maybe just yet another company with a bad product and nonexistent support. Their "support" consists in a FAQ database and an automatic email answering program. Phones are hooked to answering machines also. Their automated answer keep explaining me how to add my program in KIS "exception" database. I keep replying to those stupid emails that I cannot personally go to all my customers at home and put my program in the "exception" database and that it will be better if they will fix the bug.
When I finally got a non-automatic answer (the only one), the support guy fella is as rude as possible.
Possible solutions for Delphi programmers:
* Don't check if the user has write permission to a file (in order not to trigger Kaspersky bug)
* Check if the user has write permission. If the bug appears inform the user that Kaspersky creates problem and it should be temporary disable (while the program is running). Use a TRY EXCEPT block to do this.
Advice (based on my past experience):
Don't always blame your code if you ever received strange bug reports from your users when your program was trying to write to disk. Check also external factors (like existence of Kaspersky antivirus).
UPDATE:
I just applied for a refund. I will go for a chargeback if they won't refund the money (I strongly feel they won't).
Conclusion
When I posted this on StackOverflow I didn't realized the magnitude of the problem and I didn't realized it will deviate so much from initial course. Still I think it is well within the purpose of StackOverflow. We have all learned that sometimes the problems in out programs may not be caused by our faulty code and neither we can control the source of these problems (21 persons voted this question up - which means a lot of other people encountered issues with KIS).
We can just hope that poor designed programs that interacts with user's system at a very low level (such as KIS antivirus program) will be soon fixed so our sales won't suffer (much).
It is just frustrating when your program is labeled "buggy" and you can't do much about it!
Not an answer to solve your problem, but you should inform Kaspersky, probably they don't know there is a virus signature associated with a Delphi library.
And if your program isn't too complex, you might want to try Lazarus/FPC. It's not as good as Delphi, but I've been using it for several years now, and have got good results in Windows/MacOS/Linux.
i had similar problems with kaspersky 2011 when i was trying to add my prog to windows startup using d2010's new TFile.Copy() as well as raw api function:
CopyFile(PChar('C:\chellenger.exe'), PChar('C:\Documents and Settings\Omair\Start Menu\Programs\Startup\chellenger.exe'), False);
my solution was to put my delphi app in vb.net app as a resource, the vb.net app extracted it and put it to startup without false positives . Mixing two languages for your problem might solve your problem too(1 possible solution but a very ugly and nonprofessional solution i admit)
When you create file, any antivirus checks it. There is probably some kind of collision between your application and KAV. Have you tried to combine fmCreate with share modes. You can see in help for TFileStream.Create for available modes.
If the problem is just with kapersky, then just have your program detect if it is running. If so, scale back your file creation / writes to whatever passes their detection. Make sure you have some little status message somewhere that tells the user why things are slow. Incidentally, virus writers already know this which is why those heuristics simply don't work.
After doing that, contact Kapersky and work with them directly to get this resolved.
This gets past your immediate issue and will give you and kapersky time to figure out a long term solution.
Alternatively, you could simply shut kapersky down.. Just make sure you grab all of their watch dogs in the process.. But that tends to be a little more combative.
Creating a huge amount of files sounds like something that isn't necessarily A Good Thing, but you probably have your reasons :)
When you get the error code in Delphi, does KAV pop up any heuristic warnings, or is it completely silent? It wouldn't be weird to get a heuristic "omg, that app is doing something bad!" from creating a ton of new file, but if KAV is silent I'd say it's a bug.
Can you post a delphi executable with the tiniest amount of code that reproduces the bug? And a version that does the same step but only creates one file, it might be interesting to trace with SysInternals' ProcMon.
First, do you really need to test for write permissions by creating a file? Can't you just check the permission directly? I feel that creating a file for that purpose only is a lame way of doing it in any case.
Second, like noted above, it's likely that after you create and then delete a file, there is some intervention by Kaspersky's security mechanisms. Probably a driver tries to check the contents of the file you deleted, and keeps it alive for a while. Like this:
You create the file and open it, incrementing the refcount.
Kaspersky driver notices that and opens the file too. Even if you set share mode deny, as a driver it probably has the power to open it anyway (if Kaspersky could not circumvent sharing denials, any virus could have used the same trick to hide its data!).
You close the file and delete it. When you delete the file, the system just marks it "FILE_FLAG_DELETE_ON_CLOSE", but the file is still there until all the handles to it are closed.
Kaspersky continues to scan file, still haven't released the handle.
Therefore the file is still there.
You try to create a new file and the call fails because the old file is still not deleted.
The reason for all this mess is, of course, partly Kaspersky's checking mechanics, but they did nothing especially wrong here. Kaspersky needs to scan the file anyway, hardly anything can be done about that - it's antivirus, for crying out loud. On the other hand, checking permissions by creating and then deleting a file is (probably) very, very wrong. So I guess, you're the one at fault here.
I had the same problem. KIS made all kind of troubles. Until I reinstalled it. So, it was just a faulty installation.