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

Inno Setup - Read-Only 2

Status
Not open for further replies.

MajklPan

Programmer
Jan 11, 2023
74
CZ
Hi, I'm following up on the previous thread where the users gave me great advice.

I currently have a problem with the function of the program, some functions do not work and write the following error:
ERORR_i8z1hc.png


When I try this in the development environment, everything works, but when I create the installation file in "Inno setup", it says this error.

I thought it was in the rights of a certain file, so I set all the files in the directory to "Permissions: system-full" in Inno setup. Unfortunately, it did not remove this error, has anyone encountered this problem?

Does the rights have to be set in FoxPro even if everything works for me in the FoxPro environment? Or set it differently in "Inno Setup"

Thanks for your help with this problem

Have a nice day
 
Thanks, MajklPan.

I can't help you with your english, unfortunately, so this all has to do with repeating and pointing things out in different ways until the translation hits it.

If DBFs are installed there, the messagebox you posted earlier still doesn't match that, does it?
You erased a portion from that, which is much longer than "GPT Tisks sestav" only.

And that last screenshot of the data installation directory being [tt]C:\Users\[highlight #FCE94F]GPT Tisks sestav[/highlight]\Tables[/tt] means, that only the user "GPT Tisks sestav" can access this data.

Nobody else, and you can't change that with change of file permissions, because Widnows is very strict about who can access files in one user profile directory: Only that one user, "GPT Tisks sestav".
If ou created that folder within setup, that's not creating such a user. And nobody will have access to it. You might have thought C:\Users is a directory you can use to install your data into, you misinterpret this system directory meaning.

A directory all users can acess is C:\Users\Public\, that's the "All users" user profile directory on new systems.

And I think I now also know the root of all your problems. You must use a too old version of Inno Setup. Because things changed dramatically since Vista, about where many system directories are, especially also about Application Data for single users or all users. So what setup worked perfectly up to XP can fail in Vista or later, if it's not adapted to the new situation.

One thing is for sure: Installing data into C:\Users\GPT Tisks sestav\ is your problem, even if "GPT Tisks sestav" is actually a user and not your application name. A base directory for so called COMOMMONAPPDATA is C:\ProgramData.

Don't hardcode such paths in an inno setup script, there are specific codes for system directories. In this case this should be {commonappdata}.

And your code must address environment variable GetEnv("ProgramData") to find this system folder, which differs in Vista and later from XP or earlier.





Chriss
 
lol_a78qr0_nwmnwx.png

That's just pointing out the workarea has a CURSOR, not a table in it.

Let's talk about this once more, maybe another phrasing will help the transaltion:
Code:
1 old=RECNO()
2 DELETE
3 COUNT TO Mereno FOR NOT EMPTY(Datum_cas)
4 COUNT TO Nemereno FOR EMPTY(datum_cas)
5 SUM draha_konc TO DelkaKm
6 GO old
7 THISFORM.Grid1.SetFocus
8 thisform.Refresh

That's code you posted about one button COMMAND4. I think that is where you added the MESSAGEBOX(DBF()), is that right?
Did you once get the above filename from it, the TMP name? And did you another time get this from it?
sssssssssss_xq8ogm_ic6p8l.png


That can happen. Because the code above does not select a specific table before DELETE. It works in whatever is the current workarea. If that button COMMAND4 is only there to delete records of gptinfo.dbf, it should start with the line
Code:
SELECT gtpinfo
, because whatever you do before clicking there can mean sometimes other tables or cursors are the currently selected and activated workarea. That's a problem with this code, as it does not take care about that aspect. A button doing a DELETE in whatever is currently selected can be okay, too. If it's a general delete button but then you should be able to first specify or know what you want to delete and so such a general deletion is usually not what I would expect to be the intent.

This is a problem that's unrelated to your general file permissions problem though, you first need to address where your data should go in the installation and also then where and how you open it in the application code. That's more important to fix first.

Update: By the way, since the code somehow knows to look for data in [tt]C:\Users\GPT Tisks sestav\Tables[/tt] putting it into a more appropriate folder is only one step towards a solution. I said "...where and how you open it in the application code" because that needs to be changed, too. You don't get around to doing both changes. Change the data location in the setup and then also change how the application finds data, there should be something like a base directory it uses. I can even imagine how this path resulted even though you didn't change anything. In earlier Windows versions local application data was in a users profile documents subdirectory or in the "All Users", and there was no C:\ProgramData directory. But look into it, you see that all kind of software uses this system folder for its data or other application files, typically in a pattern of naming C:\ProgramData\Vendor\Applicationame\.

There is, by the way still something that compares to "All Users" since Vista, it's "C:\Users\Public", you can also install data into that. The problem just is, installing into another better directory does not make the rest of the code automatically find the data there. But you have to go this route and do this move of the data because you can't actually really change permissions within the branch of C:\Users\ That is the system directory for all user profiles and not of common appdata. So you have to change installation and software to work with this new situation of system folders since Vista.

Chriss
 
These kind of permission problems can be avoided totally by putting the program, data and supporting DLLs in its own directory, preferably not even on C: if there's another drive available. That way you can reinstall the OS if needed without risking your application.
 
Yes exactly, I added MESSAGEBOX(DBF()) before the DELETE statement.

However, you write that I should not store data in "users" but install it in {commonappdata}, i.e. C:\ProgramData, which I did, but I don't see that anything has changed.

I also tried installing it in the {commondocs} folder ie C:\Users\Public and it also still says Read-Only.

Thank you for your patience and time.

EDIT: Chris Miller : If I gave you the source code, could you try running it? It would certainly be easier to understand the problem.

But it doesn't make sense to me, because already in the project itself, where I have the source code stored, I run the exe file itself and it already writes a Read-Only error, so it will have nothing to do with the installation, but with fixing the access to the file. Which has to be set up somewhere.

Thank you
 
MajklPan,

when you change the setup you don't change where the code looks for the data. That's the reason it still is read-only. The location where the code reads data from didn't change just because you changed the setup.

You need to find out where in your code the data is opened and change that to the new system folder used by the setup. Otherwise the EXE of course still trie to modify the data at the place it still is there from previous installs, where it still is read-only.

Chriss
 
So you mean that I have to change the path to the gptinfo.dbf file in the code.
When I took an older project, where I run just the .exe file from the project, it works there.
Fixing the file, security and everything is identical compared to my file, I also tried the option of copying the dbf to the same place from the older project and again it didn't work.

I would not look for an error in the rights, but most likely in the creation of the exe file, where the authorization or the path should probably be set there, but I am only inferring that.
 
Problem solved.
I figured out that the file to be specified as gptinfo.dbf was included in the file compilation and I changed it to "Exclude", that fixed the problem and it now works loading those items without setting permissions. I don't understand the politics of these programs, but this is probably how they will be disqualified.
solved_upsyst.png

Thank you all for the help and practical advice.
 
There's still something to do, and I hope you will still read on or find this when you have your next question.

Since you changed a lot in the setup you either should reverse or continue and complete this.

You have more data than just gptinfo.dbf, don't you? There should be aplace for all of the dbfs and perhaps a DBC your application uses, maybe in a subfolder of your EXE, so that has to be writable to users.

It's completely unclear why there is a dbf in some subfolder of c:\users and it is there, isn't it?

So you still have to figure out where data should go and is found by the EXE.
If it's a subfolder of the EXE and you isstall this into Program Files (x86) then you kow the warnings others gave you about this, this is even a topic in the other recent thread of a problem with an application from k2a.

There is however, a very well known VFP developer Doug Hennig that has indeed made it a norm to install data into a subdirectory of an EXE, see here:


And even before you go read it (very much recommended) he's posting his Inno setup configuration as
Code:
[Dirs]
Name: "{app}\Data"; Permissions: everyone-modify
Where {app} is where Inno installs the application and the Data subfolder name may differ for you.

His argument is such an installation can even be the basis for a multi user application, if you either make it a terminal that multiple users connect to and use. It's not as good to make it a share, but it would technically also work. It would just not make all further installations automatically use this share, you'll still at least need to integrate a setup inteerviw question whether the installation is the server or a client. And then on the server you'd only need to install the data and on clients you only need the sofftware and so I would make two different etups out of that.

But you see, you have a proponent for a data subdirectory in the program files system directory.

The common use case for such an installation would be a per computer installation, though, with no shared data. And in his inno ini it would make all users able to use the same data, not just a single user.

It's also a bit funny, as Doug also has written a whole long article about Vista (that still holds true for VFP9 and any OS since Vista) that also talks about the changes in system directories made since Vista, UAC and all the consequences you face therefore in application projects. Overall it addresses almost anything you face and have to adapt in applications thaat still work up to XP. So Vista is a big turning point, indeed.

Here is that article: And a follow up for Win7 (and later):
And you find a lot that's unrelated to VFP as the effects of changes in system directory, another set of Fonts, Aero windows, and other things introduced since Vista affect all software, not only VFP software.

So read that, you will profit from knowing all these things in any development.

Chriss
 
Great, thanks for the article, I will look into it.

I would prefer to get rid of the FoxPro environment completely, since support ended in 2007, but for now we are developing this application in another environment, so it needs to be managed for some time, so I am ignorant in these matters.
 
I have one more question, so I don't create a thread unnecessarily, do you know where I could find the defined values in the field?
sdsd_w38pag.png

Such as, for example, MVD, MVH, MK.
I would need to change these values, but I went through the whole project and I can't find these values anywhere, aren't they defined in the .mem file?
I've also looked for it in the procedures and I also can't find the number that appears when the program starts.

Thank you for answer
 
Thank you for answer.

I found them where they are declared, but the point is that a certain value is already set at startup, I would need to change it, where can I find it and change it?
ssssss_k43lxs.png

It's in the variables:
MezKlik=MemoDefOstTrKlik
MezRozdVys=MemoDefOstTrRozdVysek
MezVysDol=MemoDefOstTrVyskaDolni
MezVysHor=MemoDefOstTrVyskaHorni

Thank you for answer
 
Hi,

Don't forgot create backup of file GPT_Memo.MEM.
[pre]RESTORE FROM GPT_Memo.MEM
MemoDefOstTrRozdVysek=<new value>
SAVE TO GPT_Memo.MEM
[/pre]

mJindrova
 
MajklPan,

I'm sure mJindrova's advice will work, though you might not understand it. There is a little detail omitted to first CD into the directory of the GPT_Memo.mem file, and you risk storing more than you restored with SAVE TO GPT_Memo.Mem. That sounds harmless, but the extra variables you store will be RESTOREd in the application and may override something that shouldn't be overridden.

To avoid that it would be nice to know what the software itself stores into GTP_MEMO.MEM and I'm sure you find a SAVE TO in the code which could, for example, limit this to all variables starting with the name prefix "MemoDefOst".

Then you should use the same SAVE TO the software itself uses. And finding that SAVE TO code you may even find the form doing that and saving changes of these value from within the usage of the software, which should be the safest way, as it is the intended way to change the MEM file.


I know you don't like to learn fishing: But as you already dived in as far as finding out these variables are important:
Code:
MezKlik=MemoDefOstTrKlik
MezRozdVys=MemoDefOstTrRozdVysek
MezVysDol=MemoDefOstTrVyskaDolni
MezVysHor=MemoDefOstTrVyskaHorni

The next thing to look for is where the right-hand side variables come from, and I think you didn't find code defining and setting them, or reading them from a DBF or whatever. What you know is they are set somehow, somwhere at some time in the start before these lines.

Well, this is where the debugger can help you find the source. You can make a breakpoint, a condition to stop executing and suspend code, when one of these variables (from the right-hand side) becomes existent. MemoDefOstTrKlik, for example. That's a special type of breakpoint not set at some line number of some code, but this way:

In Foxpro start the debugger, that's in its menu "Tools", item "Debugger". In the Debugger window then use the Breakpoints (CTRL+B). Change Type to "break when expression changes" and set the Expression to the variable name of interest, click the "Add" button. So you have this:
breakwhenexpressionchanges_jolv4g.jpg

You could repeat this with the other names, but finding one should find the others, too.

Keep the debugger window open, just minimize it, for example, or move it where it doesn't hinder you and start the application. Execution will suspend when "MemoDefOstTrKlik" changes from being undefined to being a declared variable. You then get a breakpoint message and can inspect what caused this. Then you will see where this comes from and I'm quite sure it is the RESTORE of the GPT_Memo.Mem file. It may point to something else, though. It could be a variable definition with LOCAL or PUBLIC. You might find it's set from some other file, whatever. That's how to find out the "origin story" of these superhero variables.

Also, bear with me one more time: New question, new thread. There is no need to avoid new threads. And if you continue a thread you don't do yourself a favor. Because:

People tend to unfollow a thread once it's solved. If it's revived, the natural assumption is, that this revival of the thread is because a problem with the same issue (by thread title) arose again. You can expect that only those who solved or contributed to solving your problem will look into it, so you get fewer people looking into it, automatically. Everyone else will just think those who solved are also best for solving the new, related issue.

So, it's a really basic rule to start a new thread for a new question. That this is still about the same software is no reason to continue a thread. I understand from your perspective it might just be one application you have to maintain and your only VFP software so this all is one thread to you. But it's not at all just one thread from the forums perspective.

Your problem isn't at all related to Innno Setup, is it? Or does it stem from your setup overwriting the user's GTP_MEMO.MEM file? I think this is configuration data, which is subject to change. And so a setup that is meant as an update should not overwrite this file. Otherwise, you reset such configuration settings to their defaults. There are cases when you have new entries in GTP_MEMO.MEM, when updating users with a new one is unavoidable, perhaps, but not always. Just another thought about what might have gone wrong.

If this or mJindrova's advice solves your problem, no reason to start a new thread, it's already cared for. But also from the perspective of a forum as a knowledgebase about questions and answers, it's best if each thread has its own topic.

Chriss
 
Chris Miller,

Thanks for the detailed explanation, I followed your procedure exactly.

Yes, the declared variables were displayed, however there is still the question of how to change these variables, it must be set by default somewhere and this is what I am looking for.
Is it possible to change the GPT_memo.mem file somewhere?
If I open this file it is not viewable.
Memo_mwgrgk.png


I would create a fiber immediately if necessary.

Thank you for your responses
 
Hi,

Variables value are saved in a file GPT_Memo.MEM.

1)run vfp

2) run next row in Command window:
RESTORE FROM GPT_Memo.MEM && read variable from file to memory

3) Change value of variable:
MemoDefOstTrRozdVysek=<new value>

4) run next row in Command window:
SAVE TO GPT_Memo.MEM && save variable from memory to file

mJindrova
 
mJindrova:
Yes, I tried it now and it works [dazed]

This is exactly what I was looking for, I didn't know that this is a rather complicated procedure compared to other programming languages.

Thank you very much for the explanation and your time, I wouldn't have come up with this myself [dazed]

Chris Miller:
Thank you also for the instructions, this way I could look up the variables, how they are declared and how I will need to change them.
 
The screenshot you have, the locals window, actually allows you to change the variables by clicking into the value column.

Well, you should look into the trace window to understand where the variables are coming from. You then can also see which path is used and which file is restored.
And then Martina already gave you the SAVE TO command you need to update the file after changing the variables.

But You now have more in the MEM file than you need.

You should look for a SAVE TO command in your whole project and then look into what variables are really saved into it. I bet ou it's using SAVE TO ... ALL LIKE Mem* or something similar. Because even a not so well versed programmer (we already sorted that out from code postings) will not want to store all variables, that includes system variables and other things you not want to have in the MEM file.

MajklPan said:
a rather complicated procedure compared to other programming languages.

The pair of commands SAVE TO and RESTORE are pretty easy to use. The only complication is that you can't edit the MEM file as you saw. I discussed this and that it should be replaced in your older thread, already. It's something that is indeed easy for the developer wanting to save a state and restore it. It's also useful to use in error handling to enable getting back to how the state of all variables was when debugging an error, for example. But it's a bad choice for storing settings, for example. Configuration data should be put into INI files or - as we use VFP, a DBF table is not a bad file type, too. The registr is another place and then also XML files, etc., etc.. It's all doable in VFP, too. But you then surely also need more than one line of code to store and to read the configuration settings.

From the programming perspective, as you also experienced yourself, a RESTORE FROM command hides away the source of whatever variables are store there and you therefore can't easily discover b source code inspection what's the source of something. It does also matter how much this is documented or not, just like in any programming language. But we already talked through all these points abot the MEm file the first time ou came around here, you just don't listen or remember.

Chriss
 
There are also other commands and functions pairing up nicely to store data in a file and read it back in and the files are then also maintainable from outside the application.

I found what you missed in the menu of your application. In thee menu zakladni_menu.mnx you have a menu item 'Konec', which means 'Quit', if google translates this correctly and it seems to do exactly that with this procedure defined for it:

Code:
SAVE TO (cCestaProgramu)+"\GPT_Memo" ALL LIKE Mem*
USE 				&& uzavøe tabulku
POP MENU _Msysmenu 	&& obnovení systémového menu
CLOSE ALL 			&& uzavøe všechny okna
SET CLASSLIB TO   	&& uzavøe všechny otevøené vcx knihovny
SET PROCEDURE TO 	&& uzavøe všechny otevøené soubory procedur
SET HELP OFF 		&& nedostupná nápovìda
SET SAFETY ON 		&& zobrazení dialogového okna pøed pøepsáním existujícího souboru
SET STATUS ON 		&& zobrazení stavového øádku
SET TALK OFF 		&& urèí, zda se zobrazí výsledky pøíkazù
SET TOPIC TO		&& urèí téma nápovìdy, když se vyvolá Help
RELEASE ALL 		&& uvolnìní všech promìnných a polí z pamìti
CLEAR EVENTS 		&& stopne proces událostí spuštìn "read events"
CLEAR ALL 
CLEAR PROGRAM

So that saves whatever changes have been done to variables starting with the name prefix MEM to the GPT_Memo.MEM file.

Actually, you should be able to just adjust your GPT_Memo.MEM file from inside the application by exiting via this menu, that's all you would need. It also points out that this is really a file that can change with any application setting and has to be kept as it was when updating an EXE. You can define a new setting into it simply b declaring another variable with that name pattern and it will be saved and restored, as long as it's in the scope of this menu procedure. Exiting with the X button of the main window you don't get the GPT_Memo.mem file to update and with the next start anything related to the settings is rest. Or with an installation providing the GPT_Memo.mem file from development, you set users to that.

What you should do right now to get rid of anything not belonging to GTP_Memo.mem is read it in with RESTORE FROM GTP_Memo.mem and then rewrite with
Code:
SAVE TO GPT_Memo ALL LIKE Mem*

You could redesign this, using XML with VFP also just needs a pair of functions CursorToXML() and XMLToCursor(), for example, or - as that stems from using a DBF as the storage of configuration data - or just use a DBF itself. A bunch of variables is quite an unstructured way of handling a few values globally available to the application.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top