I'm using Inno Setup v6.0.5. I want to allow the user to select a folder so I use BrowseForFolder. The problem is that the resulting dialog does not show any mapped drives. It shows the Network folder but on my machine (and presumably others) it won't open for some reason. Is there a way to get the BrowseForFolder dialog to show mapped drives or is there another method that can be used to allow the user to select a path with a mapped drive?
The core of the problem is not that Inno Setup doesn't show mapped drives, but rather that elevated and unelevated processes do not, by default, share mapped drives. see this article:
Mapped drives are not available from an elevated prompt when UAC is configured to "Prompt for credentials" in Windows (3035277)
What this KB article is saying, in a convoluted way, is that mapped drives between elevated and non-elevated sessions are not shared. You can tell Windows that you want to share the mappings by setting the EnableLinkedConnections registry value:
Hive: HKEY_LOCAL_MACHINE
Subkey: SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Value Name: EnableLinkedConnections
Value Data: 1
Data type: REG_DWORD
Changing this setting requires a reboot, so you can't use it for just your individual installer -- and I don't recommend using a global state to manage a local problem anyway.
Based on your comment:
I'm installing data files to the network, the software is installed on their PC. It's the answer if it solves the problem
It sounds like perhaps you could solve this problem by using a separate user-based installer that only installs the data files: Just use PrivilegesRequired=lowest in the [Setup] section and then the problem of drive mappings never arises.
Related
I'm probably just being very thick here, but it's not clear to me where I'm supposed to install 'new' user-specific programs on Windows 7 (and presumably Vista too, though I've not specifically looked at that scenario yet).
Under Windows XP (rightly or wrongly) we always installed our programs into folders under 'Program Files' and accepted that they'd be kind-of available to everyone. From what I can gather under Windows 7 I'm supposed to install my software under the user's AppData folder (possibly AppData\Local\MyApp). That makes a degree of sense, but the fact that this folder is 'hidden' by default means that we're going to have 'fun' talking our users through support stuff.
I want to install our software so that it's user specific (the Users bit in Windows 7 makes perfect sense) but I do want the user to be able to access it if required. Our program also includes a 'data' subdirectory which it needs to write into while it's running (embedded database), but as the program is intended to be single-user/standalone, the data folder being inside a user-specific folder isn't going to be a problem.
My problem is just that whole 'hidden folder' aspect of AppData. As much as I've trawled the MSDN, I can't work out where else I'm supposed to install user-specific programs. Taken one way it would seem to be something like AppData\Local\MyApp, and another way it would seem to be just as valid under the user's My Documents\MyApp equivalent.
Has anyone got a clear guide for where all this stuff goes? I found the MSDN docs confusing. :-)
Not really.
The directory that serves as a common
repository for application-specific
data for the current roaming user.
AppData is, surprisingly, for application data, not for installation (Click Once/Silverlight applications aside). You can, and should still install into Program Files, just don't expect to write into that folder.
You can install software into AppData if you want it to follow a user about in an Active Directory environment, which happens if you put it in AppData\Roaming (the SpecialFolder.ApplicationData location).
You can also install into AppData if you want the software to be available to just the user that installs it. This can be useful if, for example, you have multiple users on the same machine, who all want to run different versions of the software in complete isolation.
If you want settings to only apply on the local machine then you use AppData\Local, which is SpecialFolders.LocalApplicationData - this will make AD administrators very happy as the roaming profile size won't suddenly jump up 50Mb or whatever the size of your software is.
If you wanted to create settings which apply to all users then you're looking at SpecialFolders.CommonApplicationData
You should remember never to rely on the actual name of the directory - localisation issues mean this can change and the location does change with OS versions two. You should be using the special folder enumeration in your software, or the equivalent in your installer.
Could you not install into Program Files, but use AppData as it's supposed to be used, and store your database in there?
Windows 7 added the FOLDERID_UserProgramFiles known folder and by default this maps to %LOCALAPPDATA%\Programs. This is used by MSI when ALLUSERS=2 & MSIINSTALLPERUSER=1.
On Vista and earlier there is no canonical per-user application folder but just using %LOCALAPPDATA% is pretty common. Sadly MSI will just use %ProgramFiles% on these systems.
It's 2019, and I just installed Visual Studio Code (a Microsoft product) in the default folder of
%userprofile%\AppData\Local\Programs\Microsoft VS Code
This is probably for getting around the requirement to have an administrator or UAC prompt authorise the installation
Windows 7 folder structure is deeply inspired on Unix structure:
/usr/ -> C:\Program Files\ -> binaries: executables and dynamically linked
/etc/ -> C:\ProgramData\ -> global settings
/home/ -> C:\Users\ -> a folder for each user
~/.* -> C:\Users\Hikari\AppData\Roaming\ -> settings for each user
Windows has more folder, like My Documents for files with content produced by user, AppData Local and Roaming (which Unix usually handles with NFS).
It's about time for us developers to start using these structures. We must separate at least binary files that don't need to be replicated, global and user settings.
When a setup is installing an app, this setup should expect to have permission to write on Program Files. Once the setup is finished, Program Files should be writable only for other setups aiming to update binaries to other versions.
Please install executable files to the %programfiles% folder in Windows - a simple MSI based install package can perform an active setup for any new user who logs onto the machine to create the user specific files and folders in their profiles %appdata% folder. You see this behaviour for Internet Explorer, Adobe reader, etc. - It's the little MSI installer window that pops up the first time you log onto a machine which has those applications installed. - Thanks - a system admin :)
My opinion, for what it's worth, is that user-specific program files is just asking for trouble and is a damn stupid thing to do.
A much more sensible approach is to install different versions of your program to:
\Program Files\Your Program\Program_v0.1\Program.exe
\Program Files\Your Program\Program_v0.2\Program.exe
\Program Files\Your Program\Program_v0.3\Program.exe
\Program Files\Your Program\Program_v0.4\Program.exe
I would then place a bootstrapping launcher at:
\Program Files\Your Program\ProgramLauncher.exe
Then, the user application data folder will only contain data, including an INI/XML/Settings file that indicates the version of the program that this user is working with.
Such an approach satisfies the core tenant of keeping data and executing code separate, allows every user to run a specific version of the code, and offers a small amount of de-duplication by ensuring the same executable code is not copied multiple times across user folders.
Otherwise, go right ahead with installing programs to AppData and undoing the years it has taken us to achieve clean separation of code and data. I found this thread because I noticed that Chromium and DropBox are installing code to AppData. I'm going to uninstall those program, and change the permissions on my AppData folder to exclude execution to ensure I can easily spot other programs attempting the same BS.
I need to access a network share during the install process, and I also need to edit some registry keys. And finally, I'd like to add some shortcuts to a program that is over the network share.
To edit registry keys, I run the installer with elevated privileges. However, if I do that, I won't be able to see the network share as it is usually created without admin privileges.
There is a way to kill the installer and restart it with admin privileges, and this is fine for copying necessary files, but in order to create shortcuts that point to the network share, I would then need to downgrade my privileges again, in the middle of the Inno Setup step where it copies file, a step which I can't do anything in the middle of.
Any other options for a workaround? The only one that I found was this, which requires a registry edit (fine) and a restart (not as fine).
You can create the shortcut using some command and run it from [Run] section with runasoriginaluser flag.
See How do I create a shortcut via command-line in Windows?
Or do not kill the unelevated installer. Run it only to copy the files. And continue with the unelevated installer.
Also note that you can create a shortcut pointing to a nonexisting file.
I'm creating an installer with NSIS.
It does exactly 2 things. Creates a shortcut to an executable, and puts a dll in the system32 directory.
I have to request admin elevation to achieve the copy into system32 for the dll's
However when its running with admin rights the mapped drive disappears and becomes a UNC path. I want to keep it the mapped drive path though. Some internet research shows that when elevated to admin UNC paths replace mapping which are user specific.
How can I achieve both in the same install?
Mapped drives are per logon-session (token) and UAC uses a split-token model when elevating so there are no ways around this. See this blog post for more details.
You could elevate cmd.exe and map the drive again before running setup...
I have in hands a third party msi installer that requires to be executed by an administrator. Im trying to change that so it could be installed by a regular user.
I managed to open it with installshield and changed some obvious settings like:
"Require Administrative privileges"
But in your perspective is that even possible? I´m having a hard time changing settings and configurations and until now i´m not having any success.
Im working with InstallShield 2013 Professional and if it is possible, in wich settings do you think i should be focusing?
For instance, running as regular user im now having a 1925 error.
"You do not have sufficient privileges to complete this installation for all users of the machine"
And i feel if i correct the error, others will appear.
Thank you guys!
It's highly unlikely you can do this because it depends on too many things in the MSI package that can change the system. Any files going to restricted locations (program files, common files etc) or changes to HKLM registry keys will require elevation. MSI installs don't violate security - they don't allow a limited user to change areas of the system that are restricted.
If the environment has group policy/Active Directory you can arrange for the MSI to be deployed from a central location via Group Policy, that's the way people get around this. Otherwise on UAC systems the MSI may offer an elevation prompt that allows admin credentials to be entered.
Otherwise the vendor needs to create an install that can be used by limited users.
Well, Yes i need administrative privileges to write to locations that are shared by multiple users. In the filesystem, this means folders like \WINDOWS or \Program Files. In the registry, this means all of the hives which aren't per-user. That´s ok, i don´t need any of this.
Therefore, i thought it could be possible to change the filesystem to something like [userprofile] and rewrite the program to only use the HKEY_CURRENT_USER.
But i suspect it could be more to it than only this.
I have created an installation with inno setup. My app (among other things) after is run creates a pdf file inside a subfolder and then opens it. But windows 7 says access denied and exception pops up. What's wrong? How to grant access to subfolders using innosetup?
Here's the code snippet inside ino:
Source: "C:\Users\Someone\Desktop\NET\Animations\*"; DestDir: "{app}\Animations"; Flags: ignoreversion recursesubdirs createallsubdirs
Presumably because you're trying to copy the file from a different user's private folder. That's off-limits. You can only place files into the current user's folder (the one who is running the install). It's difficult to imagine a good reason why you'd want to do otherwise, anyway.
Try using the {userdocs} constant, instead. Use ExpandConstant to expand it to the full path.
If you need things to go in a location that will be accessible to all users, you need to run the installer with Administrative privileges. Then, you'll be able to read/write from the All Users profile directory.
EDIT: Ah, sorry. I totally missed the part of your question where you said you were trying to do this after installation. I just looked at the code and thought this was something you were having Inno Setup do during the setup process.
It's a completely different answer for something after the installation has completed. Windows 7 (thanks to UAC) doesn't let your app (or any app, for that matter) write to system folders. That includes the Windows directory, as well as the Program Files folder and any of the folders it contains. This is a security measure, intended to stop applications from running amok in places where they don't belong.
You have a couple of different options:
If you absolutely need write access to the Program Files folder, you can prompt the user to elevate your application's process. Basically, that means that you'll be requesting Administrative privileges, and they'll see a box from UAC asking them for a password.
I give more information about how you might go about doing that from a C# application in my answer to this question. You'll follow similar steps for an app written in any other language; you're just calling functions built into the Windows API.
The better option, though, is to modify your application so that it doesn't have to write to system folders. That way, you won't have to run with Administrative privileges. This is the intended model for all standard Windows applications. Microsoft has been recommending it at least since the early days of Windows 2000, but you weren't actually forced into following it until Vista.
I talk more about the various places that an app has write access to (and the various uses of each) in my answer to this question.