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

creating setup for app in win7 environment using inno setup

Status
Not open for further replies.

Nifrabar

Programmer
Mar 16, 2003
1,343
NL
Hi to all!

Just to head in the right direction:
I used to create a setup using inno-setup which places my app in a map (myApp) inside the program files map. In same myApp I use to have my data map as well as some other maps. As far as I understand this is no longer allowed using Win7?

So what would be advised? My path setting inside the app expects a data folder inside the folder containing the EXE.

TIA
-Bart
 
>My path setting inside the app expects a data folder inside the folder containing the EXE.
Well, you rather should change that need instead of looking for a location of the EXE, where this is possible.

There are system functions to determine the AppData folder which is menat for, well, app data. And you don't need a seperate routine for win7, vista and xp, if you use these.
In Inno Setup use the constants to denote sepcific system folders: {commonappdata} is the folder you will want to install your data. Inno will then use the path depending on the OS.

Your own app should then use a function to determine that path:

Code:
Function GetCommonAppData()
   #Define CSIDL_COMMON_APPDATA 0x0023
   #Define SHGFP_TYPE_CURRENT 0
   Local lcFolder

   If Os(5)>='6000'
      lcFolder = Addbs(Getenv('ProgramData'))
   Else
      lcFolder = Space(512)
      =SHGetFolderPath(_vfp.HWnd, CSIDL_COMMON_APPDATA, 0, SHGFP_TYPE_CURRENT, @lcFolder)
      lcFolder = Addbs(Left(lcFolder,At(Chr(0),lcFolder)-1))
   Endif

   Return lcFolder
EndFunc

Here you need a branch depending on OS version, because since Vista the SHGetFolderPath is a deprecated system function on the one side, and it's very easy to use Getenv('ProgramData') since Vista on the other side. But that isn't a variable set in XP.

So this function get's you that folder for XP-Win7 and should continue to work in Win8, I had no chance to test that yet.

On the other side, you can also install data into a subfolder of your program folder and use Innos feature to set permissions on folders. Inno has your situation described in it's help, too:
Inno help said:
It is recommended that you avoid using this parameter to grant write access on directories containing program files. Granting, for example, everyone-modify permission on the {app} directory will allow unprivileged users to tamper with your application's program files; this creates the potential for a privilege escalation vulnerability. (However, it is safe to change the permissions on a subdirectory of your application's directory which does not contain program files, e.g. {app}\data.)

So you also may use that way. A subfolder within program files could be a higher security risc, than putting data into CommonAppData, though. Not for the data itself, this is then modifiable and that is needed anyway. But there may be a hack to change parent folder access permissions using the permission inheritance and some security flaw, which would open doors to your applications program files and then to the general program files and other apps as well. This chance is never given for the CommonAppData folder, as that folder is on no child level of the Program Files folder. Maybe that's just my thinking and it's a nightmare, which never will happen. Indeed every thought about permissions is useless, if hackers achieve administrative privileges anyway, but then you could also not care at all about program and data location, and that would surely be careless.

So I would really recommend putting your data into CommonAppData, as that's meant for it.

Bye, Olaf.
 
Olaf,
Thanks for your explanations. But how should I handle this in my develop environment?
Swap path based on version(2) <> 0 ?
-Bart
 
Bart,

One way I handle this would be to get Inno Setup to store the path to the data directory somwhere where your app can find it. That might be the Registry, or in an INI file, or some similar place. Then, when the app runs, it looks in that path. If the data files don't yet exist, it goes ahead and creates them, otherwise it proceeds as normal.

Another option would be always to store the data in %appdata%\<your application name> (that is, in a directory specifically for your application, under the Application Data folder). Again, let the application itself test to see of the data exists, and to create it if it doesn't.

Whether these systems will work for you depends on how your app is constructed, but it should at least give you some ideas.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Why swap path at all? You're not saying you have hardcoded paths in your development, do you?

You can also have the database in CommonAppData on your pc durin development or anywhere else you like, then you just read a path from elsewhere of a config, rather than calling the GetCommonAppData() function.

Mainly you will OPEN DATABASE (cPath+"yourdatabase.dbc") and after that it doesn't matter any more, where the database is. USE tablename will find the DBF from the DBC.

In the end, yes, you may use version(2) or _vfp.startmode to decide wether you should change path, you could also check, if you find your database in the CommonAppData path inside a \yourapp\ subfolder or not and then revert to another path for development. You can do whatever you want, can't you?

Bye, Olaf.
 
While I am puzzled why you have such questions, if you programmed with hardcoded path, and relative paths still are hardcoded in relation to the setup path, and if that throws up so many problems to you, the easies tmay be to go for the second best solution and use the ability of Inno to set up modify permissions in a {app}/data subfolder.

Bye, Olaf.
 
Olaf and Mike,
Thanks for sharing your knowledge on this topic.
@Olaf
Maybe I did confuse a bit. My path-setting is always relative so not giving me any trouble.
But the default setting is coded in my develop environment.
I do have all my projects on an external drive and that drive appears with different letter e.g. E:\ or G:\ on the PC the external drive is connected to. A copy of VFP also resides on the external drive. That way I can make small updates everywhere without taking a laptop with me but just that external drive.
I need to play a bit with the knowledge I learnt from you to get an universal solution for making setups for both XP and Win7

Code:
IF VERSION(2) = 0 && runtime
	lcDefaultDir = SYS(5)+SYS(2003)+ "\"
	lcDefaultPath = ' ,data,BU'

ELSE && develop environment
	LOCAL lcDefaultDir, lcDevelopPath, lcMachineName
	lcDefaultPath	= ' ,data, foto, system, libs, code, code\tools, menu, forms,graphics,help,include,reports'
	lcMachineName 	= LEFT(SYS(0),ATC('#',SYS(0))-1)
	DO CASE
	CASE lcMachineName ='PC07256'
		lcDefaultDir  = "E:\vfp\projects\prive\"
	CASE lcMachineName ='PC03718'
		lcDefaultDir  = "X:\vfp\projects\prive\"
	CASE lcMachineName ='KANTOOR'
		lcDefaultDir  = "f:\VFP\Projects\prive\"
	CASE lcMachineName ='TARGALAPTOP'
		lcDefaultDir  = "F:\VFP\Projects\prive\"	
	CASE lcMachineName ='BVS'
		lcDefaultDir  = "F:\VFP\Projects\prive\"
	CASE lcMachineName ='P3-GATEWAY'
		lcDefaultDir  = "E:\VFP\Projects\prive\"
	CASE LEFT(lcMachineName,1) ='D'
		lcDefaultDir  = "D:\VFP\Projects\prive\"
	OTHERWISE 
	ENDCASE
ENDIF

SET DEFAULT TO 	(lcDefaultDir)
SET PATH TO 	(lcDefaultPath)

anyway,
thanks as always for spending some time on my Q

-Bart
 
Bart,

Regarding your code with the large DO CASE construct: I might not have understood this, but is the aim to set the default directory to the one from which the program itself was launched?

If so, you could replace the entire DO CASE construct with this:

Code:
SET DEFAULT TO JUSTPATH(SYS(16))

If I've misunderstood, just ignore this.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
What does that mean? You don't install in program files at all? Then why did you ask about win7 allowing data there? It doesn't matter then, at all.

Win7 still allows installers to let users choose the install Dir anywhere else on any local, network or removable drive. It's not yet shrinking down the places where files are executable. To some extend thaat's nice, to some extend it would give higher security if that would be the case. The only thing, which really has changed is, that installing files in many system folders will have permissions default to read and or execute, but not modify. You still can let your setup change permissions and you still can install anywhere else.

So you don't have a problem at all, or I still misunderstood you. You also have solved the detection of drive letters in a way I wouldn't do it, but if it works for you, well, then keep it that way. I would detect usb drive letters and then look for a certain folder within a drive to see where the drive really docked. If you ever plug in your device into a different usb port, it could get another drive letter on the same computer, this is nothing you should rely on. Windows does a device driver install not only per device (or drive in your case), but also per usb port. Next time you add a new usb thumb drive to one port, see how windows installs device drivers, then plug into a different port and see how windows again installs the device. Until you have used all ports and windows recognizes the drive plugged in anywhere. If you do so with many devices and not all at once, the drive letters assigned can be non unique, so you get problems, when attaching two drives that should get the same drive letter.

Look at drivetype and loop from "c" to "z" to see what type is attached to a drive letter, if at all.

Even if you stay with detection per SYS(0), don't hardcode that, put this into a configuration dbf, in which you can lookup GetEnv("Computername") and find the related directory.

Bye, Olaf.
 
@Mike
This construct grew while taking my app on hd and use it on different locations

@Olaf
Why shouldnot I install in program files?
That's done through Inno. The exe is than located in an app-map which resides in programfiles with subfiles in that app-map holding data, backup etc.
I am not detecting drive letters. It's just a sloppy way of making my development environment work in easy way on several machines using the external HD.

As I got confirmed from your messages that this is not always allowed in Win7 I have to update my app in a generic way.

-Bart
 
I didn't said you shouldn't install into Program Files, you reported, that your application is on a USB drive, didn't you?

Then I don't understand what you're saying, perhaps.

Bye, Olaf.
 
Olaf,
My development environment is on, as you called, USB drive.
Once compiled and employed it resides in program files on HD.

-Bart
 
OK, I get it now.

But instead of the CASE you could always simply use SYS(16) or PROGRAM() to get the location of the code and your lcDefaultDir will then be relative to that. You don't need any case statement to decide where you are, you can simply determine that.

Write a prg containing the line: ? PROGRAM(), SYS(16)
Put it anywhere and run it. You get the path of the prg.

I concluded from the data path being on different drives, that the application would also be there, as you said you install the data relative to the app.

I was overlooking you only do this for Version(2), maybe, because I prefer using _vfp.startmode, as that name makes it clearer it has to do with how vfp runs as IDE/sourcocde or EXE (or DLL).

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top