Archive: Wrong place of the shortcut under Windows 7 64-bit


Wrong place of the shortcut under Windows 7 64-bit
Hello guys,
I have a problem the shortcuts on Windows 7. I know that there are several posts concerning such problems, but not exactly my situation.
I can install my application for all users and for the current user only. The problem happens if I install it for the current user only and under Windows 7.
The application is installed correct in C:\Users\AccName\AppPath\Roaming\AppName. But the shortcut is created always in the section for all users: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyGroup. Instead of this, I expect to see the shortcut in: C:\Users\AccName\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyGroup. I thought that I might have an error in my script, but I printed the path to the shortcut and I see the following:

MessageBox MB_OK "$SMPROGRAMS\MyGroup\MyApp.lnk" ; Here I see the test "C:\Users\AccName\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyGroup\MyApp.lnk"
CreateShortCut "$SMPROGRAMS\MyGroup\MyApp.lnk" "$INSTDIR\MyApp\MyApp.exe"

Immediately after the execution of these lines of code I see that there is a shrotcut created in C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyGroup. Why?


AFAIK all you need do to is add a manifest. Use the requestexecutionlevel command.


NT6 sucks that's why, it thinks it knows better than you. But like MSG says, add requestexecutionlevel. See http://nsis.sourceforge.net/Shortcut..._Windows_Vista


I used RequestExecutionLevel user, but now I'm facing to a new problem. The DLLs in System32 can not be installed. I get "Error opening file for writing!".


To write to sys32, or any other protected directory, you need admin access. You'll have to do:
1) requestexecutionlevel admin
2) verify admin access in .onInit using the userinfo plugin
3) do an all-user install (because you're admin)
4) write all regentries to HKLM (see 3)


I made it as you suggested and made tests on several operating systems. It looks that it works. Thanks a lot.


After more tests I saw a problem. I used Windows 7 32-bit version with two accounts - "Test" (with admin rights) and "Test1" (without admin rights). I tried to install my application in account "Test1" for the current user only. I expect to have an installation folder like this:
C:\Users\Test1\AppData\Roaming\NameOfMyApp
But I have the following line in my script:
RequestExecutionLevel admin
This cases elevation to admin rights. That's ok, but the installation folder is switched to
C:\Users\Test\AppData\Roaming\NameOfMyApp (instead of C:\Users\Test1\AppData\Roaming\NameOfMyApp).
If I remove the request for admin rights, I will get the correct installation folder, but I won't be able to install the DLLs in System32.
So the question is how I can ensure correct installation in all cases admin or non-admin rights, installation for all users or for the current user, OS Windows XP or 7,... As far as I know, I can not switch the access rights during the installation.
Please, help...


You must not elevate if you want a single-user install. When installing something in Windows, you must do one of two things:
1) Elevate, and install for ALL users
2) Do not elevate, and install for THIS user.

That is how Windows is designed. You must use one of the two. Not both. This means that you cannot install to the System folder without doing an all-user install. Sorry.


(Cheater's note: The NSIS UAC plugin technically allows you to elevate and still install as user, but that is contradictory to how Windows is designed. Only for advanced users who enjoy breaking rules, definitely not recommended.)


Ok, but the RequestExecutionLevel must be outside of any functions. In the real world there is a dialog that asks the user for the type of the installation. How than I can switch the execution level?


You cannot. The requested execution level is stored in the manifest, there can only be one of those. So it's one or the other: An all-user elevated installer, or a single-user userlevel installer. Like I said, what you want is not (sanely) possible. You'll have to install your application for all users if you want access to the system dir.


I have another idea. The first tests gave me good results, but I don't know what will happen at the end. The idea is the following:

  • If all user mode is selected - do the same as before.
  • If current user mode is selected, modify the path from these ones from the file. This will guarantee that the application will not be installed in the account with administrator rights, but with the needed one. Then the installation continues as before.

Do you thing that this will work?

No, this will not work, if the user is not admin, they will elevate with a different user and then your helper app will get the admin users profile path and not the "real" path.

You could do it the other way around, install files normally as current user and then launch a mini installer that runs as admin and installs your system files...


Yes, I can do this, but it leads to many complications. I install several applications with one installer and I have for each one a separated section. Each section contains operations that must be done with user rights and and also operations that must be executed with admin rights (installation of DLLs in System32). So I prefer only to permit the possibility to install if the rights of the account are not admin. Now I have the next problem, therefore the next question. I want to check the rights in .onInit function. I can do this with the plug-in UserInfo. But if I use RequestExectionLevel Admin, the plug-in always reports admin rights. So is there a possibility to locate the original rights of the account in which the installer is started? Once more - I need the following... If the installer is started from account with admin rights, then installation for all users and for the local user are allowed. If the installer is started from account with non-admin rights, it must show a message that the rights are not enough and the installation must be aborted. This must work on Windows 2000, XP, Vista and 7. How can check the account rights?


You are confused.

1) Requestexecutionlevel does NOT elevate your installer. It only tells UAC that you *want* to elevate. If UAC is disabled, or you're on a windows version older than Vista, the requestexecutionlevel command does absolutely nothing.
2) If you request admin, and UAC is on, you will never ever ever be able to install as user. There is no way to know what the 'original' user was.
3) If you request user, or UAC is off, you will not elevate at all. This is why, if you want admin access, you must always verify admin access using the userinfo plugin.

Once again, I can not stress this enough: You can NOT do things both at userlevel and adminlevel, in one installer. It's technically 100% impossible.


Cheater's note: There is a way to work around this problem by using the NSIS UAC plugin. It allows you to launch your installer at userlevel, and then start a second installer instance as admin. This allows you to effectively do things at both levels. But an installer using this trick will become quite complex, so it's not recommended. Your funeral.


MSG, I'm really confused.
I have seen many installer that ask you to select the installation mode. That's why NSIS has MultyUser-dialog. If it is impossible to select the installation mode later, then why we need this dialog?


The problem with those installers is that they assume that the user running the installer is *already* an admin. Let's say you're on WinXP. Most people used XP from an admin account, because that's easiest. (It's also the most dangerous - this is why Microsoft changed things in Vista.) So let's say we're an admin user called Peter. If we run an installer, a 'single user' install is possible because the installer is running as the user Peter (after all, no elevation is necessary). So any 'userlevel' commands are really for THIS user. So it works.

Now let's assume we're on WinXP, but we're a *userlevel* user called Steve. Steve runs the installer, and the installer (if it's not completely stupid) warns the user that it needs admin access and quits. So, Steve does Run As Admin. From that point on a single-user installation is no longer possible, because the installer is now running as a different user. Any 'userlevel' commands (and variables such as $desktop etc) are now not executed as the user Steve, but rather as the admin user (Peter, or Administrator, or some other admin account). So if the installer still tries to do a 'single user' install, everything breaks: It's installed for the admin, not for the user who launched the installer.


Now, this story changes for newer Windows versions. Since the launch of Windows Vista (when UAC is on), there is no real admin user anymore: All users are normal users until they elevate. The only difference between a userlevel user and an adminlevel user is that the first is not allowed to elevate, while the second one is. This is why, on Vista and newer, an elevated installation must always be installed for all users: There is no way for Windows to know what user originally launched the installer.


(Note: On WinXP and older, admin users do exist. So on those windows versions you *could* offer a single-user installation choice. This is however somewhat dangerous, because if Steve does Run As Admin, you'd still end up installing for the wrong user. So again, best way is to simply force an alluser install if the installer has admin access. In other words: All installers that offer you the choice are broken.)


Well, the MultiUser option is meant for installers which do not need admin rights.
And that is still valid for Windows Vista and Windows 7 etc.


Then the only possible solution for me is to remove this possibility for my installer and install always for all users.
Thanks to all of you!


Originally posted by jpderuiter
Well, the MultiUser option is meant for installers which do not need admin rights.
And that is still valid for Windows Vista and Windows 7 etc.
Err... What? You cannot install for all users if you don't have admin access. Well, unless you're counting power users, I suppose...

Originally posted by MSG
Err... What? You cannot install for all users if you don't have admin access. Well, unless you're counting power users, I suppose...
Hmm, you're absolutely right, should have thought about that myself.
So there is no use for the MultiUser option at all anymore, actually it will be confusing for the user.
Good to know.