- NSIS Discussion
- Need to store text files in AppData folder
Archive: Need to store text files in AppData folder
SteveRussell
3rd September 2011 23:58 UTC
Need to store text files in AppData folder
Now that I am in Windows 7, I suddenly find that simple text files that my app updates per user are denied access. Until now, I have kept these profiles in a subfolder of my install directory.
I am wondering if I could get a bit of direction on how to use NSIS to find the right appdata folder and place some files in that location during installation. Of course, the folder name varies, such as 'Application Data' in XP and 'AppData' in Windows 7. I am thinking and hoping that this move will eliminate access problems.
msroboto
4th September 2011 05:48 UTC
Look up $APPDATA in the wiki.
I think that's what you want. There is a warning about how the SetShellVarContext is set.
MSG
4th September 2011 06:48 UTC
It's all in the manual.
http://nsis.sourceforge.net/Docs/Chapter4.html#4.2.3
SteveRussell
4th September 2011 08:45 UTC
Thank you, gentlemen. I did discover $APPDATA after posting, but this is a new concept for me.
I am wondering: When might "All Users" be chosen over "Current user"?
MSG
4th September 2011 17:43 UTC
If you enforce admin access for your installer (for example because you need to write to a protected directory such as $SYSTEM or $PROGRAMFILES), you must install for all users. In this case, you must use the HKLM registry hive for all registry stuff.
If you do not do anything that requires admin access, you can do one of two things:
1) Force admin-only installation anyway. This means installing for all users and using HKLM (see above).
2) Allow user-level installation. This means NOT asking for admin access, NOT writing to any protected folders, only installing for the current user, and using the HKCU registry hive instead of HKLM.
This is how windows is designed to operate, so this is how you're supposed to do it.
Anders
5th September 2011 10:48 UTC
Originally posted by SteveRussell
I am wondering: When might "All Users" be chosen over "Current user"?
I you have things that are shared with all users of your program
SteveRussell
5th September 2011 14:45 UTC
Originally posted by MSG
If you enforce admin access for your installer (for example because you need to write to a protected directory such as $SYSTEM or $PROGRAMFILES), you must install for all users.
I definitely do write to program files. But I thought that it was no longer possible to enforce admin access with RequestExecutionLevel.
Afrow UK
5th September 2011 15:48 UTC
You need RequestExecutionLevel admin but you still need to check the user is an administrator in .onInit and abort if they are not.
Stu
SteveRussell
5th September 2011 16:03 UTC
Originally posted by Afrow UK
You need RequestExecutionLevel admin but you still need to check the user is an administrator in .onInit and abort if they are not.
Stu
I would love to see an example of checking the user. Haven't found one yet.
MSG
5th September 2011 16:07 UTC
requestexecutionlevel doesn't do anything in WinXP, or in Win7 if UAC is turned off. So use both:
requestexecutionlevel admin
function .onInit
userInfo::getAccountType
pop $0
${If} $0 != "Admin"
messageBox MB_OK "Requires admin"
quit
${EndIf}
functionend
(and same for un.onInit!)
SteveRussell
5th September 2011 16:57 UTC
(Ignore this post. I had inserted code before includes.):
Thank you. I'm getting an error:
Function: ".onInit"
File: "UserInfo.dll"->"$PLUGINSDIR\UserInfo.dll" [compress] 1336/4096 bytes
Plugin Command: GetAccountType
Pop: $0
Invalid command: ${If}
------
Function .onInit
UserInfo::GetAccountType
Pop $0
${If} $0 != "Admin"
MessageBox MB_OK "Your system requires administrative permissions in order to install this software."
Quit
${EndIf}
FunctionEnd
Anders
5th September 2011 19:49 UTC
!include LogicLib.nsh
SteveRussell
7th September 2011 10:58 UTC
Should I remove related folders and data files from the appdata folder when uninstalling?
msroboto
7th September 2011 14:55 UTC
Depends what it is. If you uninstall word do you expect the .doc files to be deleted.
I don't know if that analogy works in your case.
MSG
7th September 2011 16:15 UTC
You should delete everything you don't want to keep. As simple as that.
SteveRussell
8th September 2011 23:57 UTC
I kind of like the doc comparison. My tiny data files are profiles that record user progress, otherwise meaningless when the application is uninstalled. But they could remain for re-installation.
I have never before dealt programmatically with the appdata file structure, so never had to think about some of these ramifications. I treat the register very carefully, leaving it clean at uninstall. Now I am wondering about the neighborhood rules - Is it considered sloppy to allow some files to remain in appdata when the program is removed?
MSG
12th September 2011 12:27 UTC
Originally posted by SteveRussell
Is it considered sloppy to allow some files to remain in appdata when the program is removed?
That entirely depends on your definition. "Uninstallation" implies you undo the installation, but you can define "installation" as that which the installer created (so, only the original application), or you can define it as everything that comprises and belongs to the installed application (so, both the app and its settings etc).
Note that it may also depend on the size and number of files you're leaving behind. What most uninstallers do is add a checkbox or messagebox option to delete saves/settings along with the application.
Afrow UK
12th September 2011 13:04 UTC
You should ask the user if they wish the files to be deleted. You can either use a simple MessageBox, and an uninstall component (i.e. another un. Section) or add a custom page with a check-box on it.
Stu
SteveRussell
13th September 2011 01:56 UTC
Yes, I need to give the user the choice to delete or keep the associated files. Thank you all again for your thoughts, which have clarified mine. I greatly appreciate your advice and direction.
SteveRussell
13th September 2011 23:13 UTC
Originally posted by Afrow UK
You can either use a simple MessageBox, and an uninstall component (i.e. another un. Section)....
Stu
Section, or Function?
Afrow UK
14th September 2011 11:25 UTC
You can have multiple uninstall sections along with an uninstall components page (read the docs).
Stu
SteveRussell
18th September 2011 11:02 UTC
OK, I have created un.CleanUp_Profiles as an additional Section.
Section un.CleanUp_Profiles
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Do you want to delete all Sign In id's associated with $(^Name)?" IDYES true IDNO false
true:
Delete "$APPDATA\${PRODUCT_FAMILY}\pf\*_scii.txtt"
Goto next
false:
Goto next
next:
SectionEnd
I was already conditionally deleting other files and folders in Section Uninstall, depending on whether or not other similar products have been installed in the same directory.
I don't see the docs telling me what should go inside the main section and what should not.
MSG
19th September 2011 05:45 UTC
For NSIS it doesn't matter in which section you put it. That's entirely up to you. If you want to make it an optional section, obviously all the optional files should be deleted in that section, not in another.