[RESOLVED] Runtime error 70: Permission denied
Have a database file that is password protected that my program use to define screens etc. The program only reads from this database, no writing done to it.
The database resides in the program directory where the exe is located as it is needed to do the screens etc.
I'm using Inno Setup (very new to it though) to deploy the program. In XP the program works fine, reads the database without any problems. Vista and Win7 is another story though. On some of these systems I get Runtime Error 70: Permission denied when my program tries to open/read from this database. It seems that it is only the password protected database that is affected. Two other databases that is not password protected works without a hitch.
Turning UAC (User Account Control) off on these machines solves the problem with my program opening and reading the database but I suspect will create other problems. It is of course possible that the Vista and Win7 machines that does not give this error already has it's UAC turned off. Digging the Internet it seems that there is some consensus that UAC is rubbish.
Can Inno Setup set the file permissions during setup so that the program will not encounter this problem while UAC is turned on? How?
Your help is really appreciated.
Re: Runtime error 70: Permission denied
Quote:
Originally Posted by
Bezzie
The database resides in the program directory where the exe is located as it is needed to do the screens etc.
That is a very bad idea, because database files (particularly MS Access based ones) tend to written to even if they are read only - due to lock information etc.
As such, you should be storing them in one of the AppData folders. For more information, see the article Where should I store the files that my program uses/creates? from our Classic VB FAQs (in the FAQ forum)
I'm not sure how Inno Setup deals with those folders, but from what I've seen it is a simple change.
Quote:
Digging the Internet it seems that there is some consensus that UAC is rubbish.
That is certainly the consensus among programmers who break the rules of Windows development (see my link above for the Windows 2000 developer guidelines, which were provided with VB6 in 1998), either because they don't care about doing things properly, or like in your case they aren't fully aware of their mistakes.
In my experience the majority of people (including many programmers) are happy with UAC, and are willing to put up with minor annoyances in order to reap the benefits it gives.
1 Attachment(s)
Re: Runtime error 70: Permission denied
I am in agreement with most of si_the_geek's comments above.
However there is nothing wrong with storing read-only resources in the EXE's folder or subfolders beneath it. I have seen nothing from Microsoft to discourage this, and from their descriptions and examples for proper co-existance with UAC this seems to be encouraged.
It may be possible that your problem here stems from Jet trying to create its lockfile (*.LDB). I'd almost have to guess you have blindly used some sort of manifest with your program that is telling Windows that your program is Vista-aware, probably without realizing it. This will suppress filesystem virtualization when UAC is enabled (among other things) and it can force your program to take on many responsibilities. Win9x appcompat shims are effectively disabled.
I'm surprised at how many people created WinXP programs in VB6 and never realized it also was letting them limp by, pretending they were on Win9x yet.
If you are truly opening and using the database only for reading, there is a simple answer. It is pretty much the same thing you have to do when using a Jet database stored on read-only media, such as a CD/DVD or a write-protected network share.
I have attached a demo illustrating this.
The demo creates a simple MDB if not present, then it opens the database read-only in a manner freeing Jet from he need to create and use a lockfile. I avoided opening it exclusively, so it can be open multiple times as needed. You can see this by running two copies of the demo after compiling it.
This may not actualy be your problem here, but it might point you to solutions. You might even want to take a good look at any manifest in use, because you may want to reconsider telling Windows you are Vista-aware. The use of Inno alone suggests that you are not.
Re: Runtime error 70: Permission denied
BTW: When it comes to application compatibility in Windows 2000 and later, this involves much more than the few shims activated by explictly going into the EXE's properties and setting an OS compatibility level. This just does a few things with version lies for Windows and a few core libraries, and sets up some simulated DOS memory structures (extended memory, etc.).
Windows applies many more shims based on what it senses from the way the program itself behaves. Some are "learned" from program crashes the first run or two.
Re: Runtime error 70: Permission denied
Thanks guys.
My program is a straight forward database app. No rocket science or anything. This is the only problem found (so far?) on machines running Vista and Win7. Hopefully there isn't any more.
I have already started fixing the program so that all datafiles resides in LOCAL_APPDATA directory to avoid the problem in future. Will have to figure out something in the meantime to fix the ones already deployed.
I assume this will also apply to .txt files that the program create and delete?
Re: Runtime error 70: Permission denied
Quote:
Originally Posted by
Bezzie
I have already started fixing the program so that all datafiles resides in LOCAL_APPDATA directory to avoid the problem in future. Will have to figure out something in the meantime to fix the ones already deployed.
What I do in situations like that is add a check to the start of the program, to do a quick Dir to see if the file is in the new location.
If it's there then everything is fine, if not the file gets copied from the old location and the new method can then be used.
Quote:
I assume this will also apply to .txt files that the program create and delete?
Absolutely.
Re: [RESOLVED] Runtime error 70: Permission denied
LOCAL_APPDATA is a per-user location. This could work fine for files every user has a private copy of but it won't help much for something like a database the program reads from for all users.
It may be worth noting that you should never put files there, but in an application folder you create under LOCAL_APPDATA. The concept is much like using the Program Files folder.
Re: [RESOLVED] Runtime error 70: Permission denied
Yes, I'm using a subfolder in LOCAL_APPDATA. My app is a single user app that must only work on the computer where it were installed for the user who installed it.
Re: [RESOLVED] Runtime error 70: Permission denied
But if you install into Program Files you are making the program available to any user on the computer.
You'll probably get away with what you're doing, but it doesn't sound correct at all. Per-machine data like your database would go under Program Files if read-only, or under CommonAppData (now known as ProgramData) if read/write.
Re: [RESOLVED] Runtime error 70: Permission denied
Wouldn't the program only be available to the user that installed it, when it is installed in Program Files? And then the datafiles in Local Appdata will only be available to that user as well?
Or do I have the cat by the tail?
Re: [RESOLVED] Runtime error 70: Permission denied
No, normally when a program is installed into Program Files it is available to all users. If COM libraries are incorrectly registered they may end up registered "per user" for just the installing user though, making the program fail to run for other users.
LocalAppdata is a per-user location, but it is meant for things like per-user settings files and such.
Under Win 6.x (Vista/Win7) most installers must run elevated. This may mean the installer runs under a different account than the user normally uses. What then? The user running your program will trip trying to find your database in the Admin user's LocalAppdata - which they can't see. This is why we have CommonAppdata.
To install an application for one user you don't put it into Program Files. Until Windows 7 there was no "blessed" location to use though. These now go into application folders under LocalAppData\Programs, but you can use this location for per-user installs in earlier OSs as well. You may have to create the Programs folder first though within your installer.
This allows un-elevated installs, but it is an unprotected location unlike Program Files. There is a risk here because such programs are subject to easy infection by trojans and such so it is not generally recommended to do per-user installs.
Installation isn't a trivial topic. The malware guys just make it harder too.
Re: [RESOLVED] Runtime error 70: Permission denied
So I gather that CommonAppData is better to use than LocalAppData?
Re: [RESOLVED] Runtime error 70: Permission denied
It would be, for data used per-machine (i.e. for multiple users). That's an entirely separate issue from things like temporary files created by/for each user during execution, which still should be in some per-user location.
Note that CommonAppData has complex security attributes, and folders and files created under there inherit "owner" security. The person creating the file or folder has full rights while others only get read/execute access. Normally if different security is desired (as when putting a R/W MDB there) the installer should create the folder and set appropriate security on it.
Re: [RESOLVED] Runtime error 70: Permission denied
Sorry this is an old thread but I've just noticed this error showing when I run one of my database apps. I always use:
Code:
Private Sub Form_Load()
On Error GoTo ErrHandler
If App.PrevInstance = True Then
MsgBox App.Title & " is already running!" & vbCrLf & "Only run this app once.", 16, App.Title & " Running"
Unload Me
'Unload Me deletes the database extracted from a resource file
End If
Which as always worked before but if I recompile the same app with a different name and try to run both apps it shows this Permission denied 70 error because they are trying to use the same database.
If App.PrevInstance = True then it should only allow one app to run at one time.