You are here

nsis help: redirect APPDATA

31 posts / 0 new
Last post
agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
nsis help: redirect APPDATA

Gluxon looked at the code and we both are getting errors. I'm going going to post on the HandBrake forum and see what I can find out what to do about the errors. If I cant figure out what to do I have two other choices I can do to make it work Move the folders in appdata (I rather not do that in case the computer get turned off or the usb gets unplugged ) Or I can make a patch for HandBrake to make it portable.

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
I just checked the Firefox

I just checked the Firefox launcher and it doesn't redirect APPDATA at all - it backs up, then restores, FF's APPDATA folder.

You can probably adapt my TopOCR launcher to handle this; just change the backup & restore locations.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
That's working on now. I'm

That's working on now. I'm trying to see if there is something like what im looking for to make things easer.

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

BuddhaChu
BuddhaChu's picture
Offline
Last seen: 7 years 5 months ago
Joined: 2006-11-18 10:26
Here's how I handled saving

Here's how I handled saving settings the old fashioned PortableApps way (two years ago). The code may not work nowdays, but the comments could help you git-r-done. Scroll over to the right to read them.

    SkipSplash:
        IfFileExists `$PROFILE\Tick5.ini` "" MoveIni                            ; Check if local Tick5.ini exists --  No: Goto MoveIni
            Rename `$PROFILE\Tick5.ini` `$EXEDIR\Data\settings\Tick5.ini.bak`   ; Backup the local machine's Tick5.ini file 

    MoveIni:
        IfFileExists `$EXEDIR\Data\settings\Tick5.ini` "" Execute               ; If settings saved from last time -- No: Run program to generate a new ini
            Rename `$EXEDIR\Data\settings\Tick5.ini` `$PROFILE\Tick5.ini`       ; Copy ini back to profile dir

    Execute:
        ExecWait `"$EXEDIR\App\Tick5\tick5gui.exe"`
        Rename `$PROFILE\Tick5.ini` `$EXEDIR\Data\settings\Tick5.ini`           ; Save settings back to portable
        IfFileExists `$EXEDIR\Data\settings\Tick5.ini.bak` "" TheEnd            ; Check if local Tick5.ini file backed up? 
            Rename `$EXEDIR\Data\settings\Tick5.ini.bak` `$PROFILE\Tick5.ini`   ; Return original ini file to the local machine

Cancer Survivors -- Remember the fight, celebrate the victory!
Help control the rugrat population -- have yourself spayed or neutered!

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
That's almost exactly what

That's almost exactly what the FF launcher was doing, from what I could tell.

btw, agdurrette, you will almost certainly want to use LogicLib...

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

BuddhaChu
BuddhaChu's picture
Offline
Last seen: 7 years 5 months ago
Joined: 2006-11-18 10:26
hmm...need to check my glasses

I think I read the original problem wrong. I thought it said the OP wanted a way to backup the files in APPDATA and keep using that location, not redirect the launcher to use data stored in a different location.

Mah bad. Sad

Cancer Survivors -- Remember the fight, celebrate the victory!
Help control the rugrat population -- have yourself spayed or neutered!

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
Is LogicLib what you are

Is LogicLib what you are using?

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
Yeah, I use LogicLib to make

Yeah, I use LogicLib to make sure my code stays neat & clean. (As a matter of fact, I believe all portable apps are supposed to be using it now)

For the actual file backup/resume, I'm using the ReName function; for the registry backup/resume, I'm using Registry.nsh

I'm going to drop a new comment in here, with the relevant code portions attached.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

digitxp
digitxp's picture
Offline
Last seen: 12 years 6 months ago
Joined: 2007-11-03 18:33
LogicLib

When I learned C (just a little) NSIS became this big mess of spaghetti.
Yeah, all portableapps should be using it now.

Insert original signature here with Greasemonkey Script.

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
How I do it

Here's the relevant stuff from my TopOCR launcher. I actually copied some of this (the Registry backup/restore code) from the 7-Zip launcher, then modified it to work with TopOCR. You can probably do the same for Handbrake.

Anyway, here you go:

Includes:

!include LogicLib.nsh
!include Registry.nsh

TopOCR file handling

       INIBackup:
       		${If} ${FileExists} "$WINDIR\topocr.ini"
                      ReName $WINDIR\topocr.ini $WINDIR\topocr-BackupByTopOCRPortable.ini
                ${EndIf}

        RestoreTheINI:
                      IfFileExists "$SETTINGSDIRECTORY\topocr.ini" "" RegistryBackup
                      ${If} ${FileExists} "$WINDIR\topocr.ini"
                            Delete $WINDIR\topocr.ini
                        ${EndIf}
                      CopyFiles $SETTINGSDIRECTORY\topocr.ini $WINDIR\topocr.ini

	SetOriginalINIBack:
                        ${If} ${FileExists} "$WINDIR\topocr.ini"
                            Delete $WINDIR\topocr.ini
                        ${EndIf}
                        
                        ${If} ${FileExists} $WINDIR\topocr-BackupByTopOCRPortable.ini
                              ReName $WINDIR\topocr-BackupByTopOCRPortable.ini $WINDIR\topocr.ini
                        ${EndIf}

TopOCR Registry handling

	RegistryBackup:
		StrCmp $SECONDARYLAUNCH "true" LaunchAndExit
		;=== Backup the registry
		${registry::KeyExists} "HKEY_CURRENT_USER\Software\SubSystems-BackupByTopOCRPortable" $R0
		StrCmp $R0 "0" UpdatePaths
		${registry::KeyExists} "HKEY_CURRENT_USER\Software\SubSystems" $R0
		StrCmp $R0 "-1" UpdatePaths
		${registry::MoveKey} "HKEY_CURRENT_USER\Software\SubSystems" "HKEY_CURRENT_USER\Software\SubSystems-BackupByTopOCRPortable" $R0
		Sleep 100
	
	UpdatePaths:
		ReadINIStr $0 "$SETTINGSDIRECTORY\topocr_portable.reg" "HKEY_CURRENT_USER\Software\SubSystems" `"TopOCR"`
		StrCmp $0 "" RestoreTheKey
			StrCpy $1 $0 "" 3 
			StrCpy $2 $EXEDIR 1 ;current drive letter
			StrCpy $0 `"$2:\$1"`
			WriteINIStr "$SETTINGSDIRECTORY\topocr_portable.reg" "HKEY_CURRENT_USER\Software\SubSystems" `"TopOCR"` `$0`
	
 	RestoreTheKey:
		IfFileExists "$SETTINGSDIRECTORY\topocr_portable.reg" "" LaunchNow
	
		IfFileExists "$WINDIR\system32\reg.exe" "" RestoreTheKey9x
			nsExec::ExecToStack `"$WINDIR\system32\reg.exe" import "$SETTINGSDIRECTORY\topocr_portable.reg"`
			Pop $R0
			StrCmp $R0 '0' LaunchNow ;successfully restored key

	RestoreTheKey9x:
		${registry::RestoreKey} "$SETTINGSDIRECTORY\topocr_portable.reg" $R0
		StrCmp $R0 '0' LaunchNow ;successfully restored key
		StrCpy $FAILEDTORESTOREKEY "true"

	SetOriginalKeyBack:
		${registry::DeleteKey} "HKEY_CURRENT_USER\Software\SubSystems" $R0
		Sleep 100
		${registry::KeyExists} "HKEY_CURRENT_USER\Software\SubSystems-BackupByTopOCRPortable" $R0
		StrCmp $R0 "-1" TheEnd
		${registry::MoveKey} "HKEY_CURRENT_USER\Software\SubSystems-BackupByTopOCRPortable" "HKEY_CURRENT_USER\Software\SubSystems" $R0
		Sleep 100
		Goto TheEnd

Hint: Use the NISEdit search function to locate those section labels in TopOCR.nsi. The code will be much easier to read & understand when taken in context (and also with proper NSIS formatting).

HTH!

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

TaffinFoxcroft
TaffinFoxcroft's picture
Offline
Last seen: 10 years 3 months ago
Developer
Joined: 2006-12-14 17:24
Redirect?

Is there a reason that people don't use this anymore?

System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("APPDATA", "$SETTINGSDIRECTORY").n'


(Redirects APPDATA to $SETTINGSDIRECTORY)
It's used in quite a few launchers, if I recall correctly. Plus it works and avoids any of the hassles of moving files.

But there’s no sense crying over every mistake,
You just keep on trying till you run out of cake.

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
Cool . Wil that also change

Cool :). Wil that also change APPDATA for other programs that use APPDATA?

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
yes

yes. I wouldn't recommend doing it; backup & restore the Handbrake %APPDATA% folder instead. Look at the Firefox launcher to see how to do it... you could also modify the TopOCR launcher.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
@computerfreaker Just so you

@computerfreaker
Just so you know, Im not ignoring you, I am working on what your saying to do, I'm trying to find out how to move a folder with LogicLib, but while I am looking for that I'm also trying to get this working in hopes of less code.

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
yes, I know you're not

yes, I know you're not ignoring me, you're just trying to do things in a better way. Smile

For moving a folder with LogicLib, try something like this... it's off-the-cuff and totally untested, so it might not be perfect, but it should be close.

!include LogicLib.nsh

${If} ${FileExists} "$APPDATA\Handbrake"
     ReName "$APPDATA\Handbrake" "$APPDATA\Handbrake-BackupByHandbrakePortable"
${EndIf}

I don't recall how NSIS recognizes special folders; you might need to change $APPDATA to something else. Other than that, I believe that will cover you...

EDIT: nvm, just read gluxon's APPDATA redirection below. Hope you can get that working!

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
Did not work :/

Did not work :/

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

gluxon
gluxon's picture
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2008-06-21 19:26
Wait, what's wrong with

Wait, what's wrong with modifying the environment variables?

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
Do you know how to do that?

Do you know how to do that? That was agdurrette's original plan, but neither of us has been able to find a launcher that does it. Even the FF launcher, AFAICT, just backs up & restores the FF prefs folder in APPDATA.
Also, idk about him, but I've been unable to find any information on what I believe is the correct system call: SetEnvVariable(APPDATA)

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

gluxon
gluxon's picture
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2008-06-21 19:26
Actually, I do know how to do

Actually, I do know how to do that Biggrin

Here's the syntax used in most launchers (taken from Python Portable).

System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("APPDATA", "$SETTINGSDIRECTORY").r0'

Just so you know, the modified environment variable only applies to the launcher and it's launched processes. Handy, eh?

The Call is also in Eclipse Portable, can't believe you guys never looked in there Sad

BuddhaChu
BuddhaChu's picture
Offline
Last seen: 7 years 5 months ago
Joined: 2006-11-18 10:26
Modifying the location for

Modifying the location for %APPDATA% would be very bad for your system since it's a Special Folder and all apps use it. Even temporary reldirection would be bad since you don't know what else is running on the user's machine. Chances are (according to Murphy's Law) another application will need to use the folder during the time you have it redirected.

http://en.wikipedia.org/wiki/Special_Folders

Cancer Survivors -- Remember the fight, celebrate the victory!
Help control the rugrat population -- have yourself spayed or neutered!

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
Ah! So that's why even FF

Ah!
So that's why even FF doesn't redirect %APPDATA%!

I reckon the backup/restore is your best (read: only) bet, agdurrette.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

gluxon
gluxon's picture
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2008-06-21 19:26
Actually, the system plugin

Actually, the system plugin only affects the launcher and it's launched apps.

http://nsis.sourceforge.net/Setting_Environment_Variables_Examples

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
If I can just get it to work.

If I can just get it to work.

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
i have the code up if you

i have the code up if you want to look at it

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 8 years 9 months ago
Joined: 2007-04-15 21:08
My turn

OK, it's time for me to try and clarify everything.

  1. There are four main ways used of finding out where %APPDATA% is.
    1. Through a DLL call, SHGetFolderPath (there are a few variants of it like SHGetSpecialFolder in various stages of deprecation and OS support but they all do the same thing). This is the way you're "supposed" to do it, and how it's normally done.
    2. The environment variable %APPDATA%. This is common, but not the way it "should" be done.
    3. In the registry, in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\AppData. (This should not be used. There's actually a value in that key !Do not use this registry key with the value "Use the SHGetFolderPath or SHGetKnownFolderPath function instead"!)
    4. %USERPROFILE%\Application Data. Yes, I have actually seen this in, I think, three applications. (Don't use this one ever.)
  2. A call with SHGetFolderPath can only be handled in one way; for an old completely working example, see my AppData redirection script.
    1. Note that %APPDATA% is %USERPROFILE%\[something]. That [something] is "Application Data" on Windows XP (English), varies between translations, and on Vista/7 is "AppData\Roaming" (note that extra subdirectory, it's a real trouble with handling this).
    2. Set %USERPROFILE% to your new location.
    3. Set %APPDATA% to the new %USERPROFILE%\[something] - it must be the same subdirectory layout as it was before!
  3. Changing %APPDATA% and/or %USERPROFILE% via Kernel32::SetEnvironmentVariable applies to the current process and all spawned sub-processes.
  4. If you change %APPDATA% other than in the way described two points up (in parallel with %USERPROFILE%, as the correct subdirector[y|ies]), the SHGetFolderPath call will return an empty string (which can break some applications, and can make others look for a different location which may even be useful, though inadvisable).
  5. The native file selection dialogues (open/save) don't work with redirected USERPROFILE, as they look for the location of the buttons on the side and can't find them - and so you'll never be able to select a file (the main window loses focus and then gets it again and the file chooser never comes up).
  6. Because sub-processes get the same things, the problems in the above two points apply to any processes that may be spawned. And so, for that reason, an application like Firefox couldn't possibly use an APPDATA redirect as it can start arbitrary processes which might break horribly.
  7. I think I've explained all in my mind just now... if you have any more questions, just post them and I should be able to answer them. (I did a lot of research into the workings of %APPDATA% about a year ago when I was trying to work with Inkscape.)
  8. My final piece of advice is, look at the source code and see if you can find an alternative settings location switch (maybe it searches for an environment variable first or something like that). If not, request it as a feature or better still offer a patch to do it (I did that last with Inkscape which is why Inkscape Portable 0.47 works by setting the INKSCAPE_PORTABLE_PROFILE_DIR environment variable). A quick look seems to indicate that HandBrake is using the C# Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) which is SHGetFolderPath, so either move data back and forth or try to patch it or ask them to.

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
MSDN

I don't have Handbrake installed on my system, so I can't test this, but it looks like you're not doing it quite the way MSDN would like...

MSDNExample 2

Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process.

If you want the child process to inherit most of the parent's environment with only a few changes, retrieve the current values using GetEnvironmentVariable, save these values, create an updated block for the child process to inherit, create the child process, and then restore the saved values using SetEnvironmentVariable

Unfortunately, I don't know how to do this in NSIS.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

Chris Morgan
Chris Morgan's picture
Offline
Last seen: 8 years 9 months ago
Joined: 2007-04-15 21:08
As I said

As I said just above, don't touch it. Anyhow, SetEnvironmentVariable is exactly what the System::Call is doing: but as I said above, you can't do it (especially with .NET applications; I suspect strongly without having tested it that USERPROFILE+APPDATA redirection won't work at all with .NET applications). Just move it.

I am a Christian and a developer and moderator here.

“A soft answer turns away wrath, but a harsh word stirs up anger.” – Proverbs 15:1

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
App data redirect is not

App data redirect is not working. Will post on the HandBrake forum and see if there is any thing I can do.

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
I hate to say this, but you

I hate to say this, but you might want to just backup & restore the Appdata folder like most other launchers... that's probably the easiest way.

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

agdurrette
Offline
Last seen: 3 months 3 weeks ago
Developer
Joined: 2008-01-16 13:55
I edited the original post

I edited the original post which explains why I dont want to do that. But I am going to do that for now just so there will be something for people that want handbrake portable. It looks like I will have to rename the folders to be able to move it.

Also: did you get the reply to your email?

"It's just an online installer. It's not going to mug you.", JTH
"The shell is the key to unlock Linux's greatest advantages."

computerfreaker
computerfreaker's picture
Offline
Last seen: 12 years 6 months ago
Developer
Joined: 2009-08-11 11:24
I understand why you don't

I understand why you don't want to do the backup/restore thing, but almost every other launcher does... you might want to reconsider. (Heck, even the Firefox launcher backs up & restores APPDATA...)

I got your e-mail reply, thanks!

Happy New Year!

"The question I would like to know, is the Ultimate Question of Life, the Universe and Everything. All we know about it is that the Answer is Forty-two, which is a little aggravating."

Log in or register to post comments