Getting Application Data folder for every user - inno-setup

In my application, every user has its own settings, that I save to a subdirectory in that user's Application Data directory. During uninstall, I want to delete those settings for every user on the computer. How can I do that in Inno Setup?
In other words, I need to get a list that contains Application Data directory for each user (not the shared Application Data directory), so that I can delete the MyAwesomeApp directory from there. Is there some way to do that?

You can't, due to the design of Windows.
The same design stops you accessing the profile folders too.
On top of this, it's accepted best practice to leave the user's data behind in case they want to reinstall it, roaming profiles, etc.

Assuming that your uninstaller runs with administrator priviledges, you can just get the User directory and then enumerate all the user directories there.
You can run an executable from Inno Setup written in whatever language you want. In it you can first get the current user's Application Data directory, using the SHGetSpecialFolderPath function. It would look something like this for Win7:
c:\Users\MyUser\AppData\Roaming\
You can use GetUserName to get the user's name (MyUser in this case), and find the parent directory and split the string to the parent directory "C:\Users\" and "AppData\Roaming\". You can then use FindFirstFile/FindNextFile to enumerate all users directories, and just append the second part "AppData\Roaming\" to them, and check if the file exists. By splitting the directory you get from SHGetSpecialFolderPath you ensure it would work both in XP (which would return something like C:\Documents and Settings\MyUser\Application Data") and in Win7. Basically you just replace MyUser with all the users' names in the string returned by SHGetSpecialFolderPath.
I have no idea if this avoids OS security or if it works with roaming users.

Related

How do a restrict create file in directory while allowing delete file

I have a regular linux filesystem and part of it is used with sftp.
My goal is for sftp-user to list and get files in a subdirectory.
The user must also be able to delete files in that subdirectory.
And finally, I do NOT want that user to be able to upload files into that subdirectory.
I struggle with the filepermissions for this subdirectory.
It seems you cannot do this with file system permissions alone.
As described here, creating or deleting a file is actually a modification of the directory that contains the file. For that, the user needs to have a "w" permission to this directory. But at the same time, your requirements contradict each other - the user can either both create and delete files, or none of the above.
Apparently you need some kind of an additional authorization mechanism (maybe some web service, or a remotely callable script) to delete or upload the files, and then apply the authorizations there.
Edit:
For instance, you could create a REST webservice running with a separate user account that has "w" permission to the directory. You need to perform very strict checking of the passed arguments and authenticate the users, otherwise a hacker could wreck your system.

Install sample documents to users personal folder upon running application

I have a Basic MSI Project in InstallShield 2012 Spring. This project installs sample documents to the current user's Documents folder (Not the Public Documents folder). When I then log onto another user, I see the application installed, but I do not see those sample documents in the second user's Documents folder (this makes sense). My question is, is there a setting in InstallShield or a way to have the sample documents install for this second user when the second user launches the application? Can launching the application detect that there are files missing in the user's Documents folder and then trigger a repair?
While this is possible, I would not recommend it. The user should control what goes in his or her documents folder; the large number of applications out there that do not respect this is not a good reason for another not to do so. Instead the application should have a way to browse the samples, open them as templates, etc., and then allow the user to save them in the documents folder. If you need them to start in the documents folder, have the application copy them in, and track somewhere that it has done so.
If you do try to automatically install these through Windows Installer, the simplest approach is to make per-user components with key files reflecting the documents location, and ensure your application's shortcuts are advertised. Launching through an advertised shortcut will scan for missing key files, and then auto-repair will install them. But auto-repair is not an experience that users like, and this approach will replace the files if the user deletes them all. (Alternately you can use a per-user registry key as the indicator, which may be less likely to be deleted.)

source code location for debugging multiple instance of an application

Hi have an application running separateley (1 instance for customer) in different folders, 1 per each customer.
Each customer is a separate user on my machine.
At the moment I have the source code in each of these folders where I rebuild the code per each instance. Would it be better if I do something like the following?
create a shared folder where I build the code
deploy the binary in each user folder.
allow permission for each user to access the source code in READ ONLY mode.
when it is time to debug, by using gdb in each user folder will allow to read the source code and debug will happen.
Do you think that this could be a better approach or there are better practice?
My only concern is that each user has the chance to read the source code, but since the user will not access directly his folder (it is in my control) this should not trouble me.
I am using CENTOS 6.4, SVN and G++/GDB.
in different folders
There are no "folders" on UNIX, they are called directories.
I rebuild the code per each instance
Why would you do that?
Is the code identical (it sounds like it is)? If so, build the application once. There is no reason at all to have multiple copies of the resulting binary, or the sources.
If you make the directory with sources and binaries world-readable, then every user will be able to debug it independently.

Setting up users' home directories before they use mintty for the first tme

I'm trying to set up some Cygwin users on a Windows 2008 Server (that I have Administrator privileges on) but I'm struggling to get their home directories set up.
Usually, if a user runs mintty as a login shell when their home directory doesn't exist (e.g. the first time they use "Cygwin Terminal"), the home directory gets created and copies of the the skeleton .bashrc, .profile, etc., from /etc/skel are added to it.
The problem I have is that I want to add some setup to the .bashrc for these users without changing the skeleton version (these settings won't necessarily be applicable for all future users).
I've tried creating the directory and copying the files over manually, but I can't then change the user/group ownership to the intended users - I get a "Permission denied" error from chown.
So, questions:
Why can't I (or how can I) get chown to assign ownership of a directory/file that I own to another user/group?
Is there actually a better way of creating a user's home directory and copying the skeleton files so I can modify them? (I'd like to avoid having to rely on the users doing something themselves to make the changes after they've logged in for the first time)
Answer to question 1: Because I wasn't running the Cygwin shell as an adminstrator (i.e. right-click the Cygwin Terminal in the Start Menu and select "Run As Administrator", then the chown/chgrp both work as expected)
Answer of sorts to question 2: there is no magic involved in setting up the user's home directory for the first time: it's done by the default profile that bash executes if it can't find the user's home directory.

Accessing C:\ drive on Windows 7

I have full admin privileges on my Windows 7 machine but when I run my application which creates a file on c:\ drive I get error code 5 (Access is denied). I know windows 7 doesn't allow creating files in protected areas like c drive and program files and file explorer brings up 'administrative' message box if I copy a file there from somewhere else after which it does allows but can my application obtain write level access?
In my application, user gets to pick the folder where they want to create the file so if they choose c:\ drive s/he will obviously get this error which is not desirable.
void CTestDlg::OnBnClickedButtonCreate()
{
CFile f;
CFileException e;
TCHAR* pszFileName = _T("c:\\test.txt"); // here i am hard coding path for simplicity.
if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e))
{
TRACE(_T("File could not be opened %d\n"), e.m_cause);
}
}
As far as I have researched it seems I can't by-pass the UAC dialog which is fine but my application don't even present it (which is understandable as well) but what are my options?
I see my only option is to detect this in my own application if this is Windows 7 OS and than check for file path before creating the file and present a more user friendly message 'windows 7 doesn't like you to create file in this folder, choose a different folder or go back to xp'. Is this scheme the way to go on Windows 7? Is there any other way?
As Kolink noted, your application needs to run with administrator privileges. In order to do that automatically, embed a manifest as explained here.
EDIT: For VS2010: Project Properties > Configuration Properties > Linker > Manifest File Change the 'UAC Execution Level' to the desired value.
Either don't try to write to protected areas, or require that your application be run with permissions (right-click => Run as Administrator).
I know I don't like random files appearing in my root - I like my files organised.
If it's the user who provides the path, then you should inform them that the file cannot be saved to this location and ask to provide another name.
Usually the shell, GetSaveFileName function, checks whether the new file can be created in the selected directory before returning, see flag OFN_NOTESTFILECREATE in description of OPENFILENAME structure.
Another option is to handle such situation and to show UAC confirmation yourself. But this solution requires much more effort than it's really worth. You can't elevate the current process, so the operation of saving the file to a protected area has to be implemented in another process. At the same time your current process has the data to be saved, so you'll have to implement the communication between the two processes. Read Designing UAC Applications for Windows Vista for more information.

Resources