InstallScope="perMachine" in wix makes no difference - wix

Hi i need my application just to work in administator mode and all users mode.(ie)It should work in all the modes.
I have created setup in WIX and after surfing a lot i came to know that setting InstallScope="perMachine" in package makes our application work in all the modes. But i found that only it shows our application under Add\Remove programs in all logins(admin or other users).
(ie): I am able to work my application in administrator mode and if i logged in as any user then my application is not visible for working.Its just appears in Add\Remove programs.
My requirement is i need my application work in all the mode,administrator,logins,all users too.
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" ></Package>
Even i tried allUser option in InstallScopeDlg.
I need my application should work for all users including administrator too

In the Setup.wxs file add the following line
<Property Id="ALLUSERS" Value="1"></Property>
The file should look like :
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="programName"
Language="1033"
Version="1.0.0.0"
UpgradeCode="183CC369-D86F-43B3-99E7-A82A16335E52"
Manufacturer="CompanyName">
<Package Description="#Description"
Comments="Comments"
InstallerVersion="200"
Compressed="yes"/>
<!--
Source media for the installation.
Specifies a single cab file to be embedded in the installer's .msi.
-->
<Media Id="1" Cabinet="contents.cab" EmbedCab="yes" CompressionLevel="high"/>
<!-- Installation directory and files are defined in Files.wxs -->
<Directory Id="TARGETDIR" Name="SourceDir"/>
<Feature Id="Complete"
Title="programName"
Description="programName"
Level="1">
<ComponentRef Id="programNameFiles"/>
<ComponentRef Id="programNameRegEntries"/>
</Feature>
<!--
Using the Wix UI library
WixUI_InstallDir does not allow the user to choose
features but adds a dialog to let the user choose a
directory where the product will be installed
-->
<Property Id="WIXUI_INSTALLDIR">INSTALLDIR</Property>
<Property Id="ALLUSERS" Value="1"></Property>
<UIRef Id="WixUI_InstallDir"/>
</Product>

The Program Files folder cannot be updated by limited users. Just because you have a per machine install doesn't mean that Windows Installer will violate the security rules by allowing limited users to write there!
The most likely thing that is happening is that admins install successfully to Program Files because they have the privileges to do that. Limited users cannot write to Program Files, so the files get diverted, most likely to C:\ProgramData
When you say "the app is not working" for limited users I'll guess that it may be a security issue - it needs admin privilege because it tries to write/update restricted locations or registry entries. In other words your app will only work for limited users if it restricts its activities to those permitted to limited users. If the app is not working then debug it - it's impossible for anyone here to say why it's failing without a lot more information. That's an app issue, not an install issue.

Related

ICE03: Invalid Language Id. Solution without suppressing the retrieval of file information

I have a Setup Project for WiX v3 in Visual Studio. When building I am getting the same error on two different files. I would like to avoid this error without suppressing the retrieval of file information. Ideally I want to solve this with changes to the xml to make it easier for my coworkers to make changes in the future.
ICE03: Invalid Language Id; Table: File, Column: Language
The problem with both files is that they have a language of 1252. Both are dll's from the mid 90's and published by someone else.
I have read that I can pass -sh to light.exe to suppress retrieval of file information. Or I can skip ICE03 when running light. I would rather not do that since I could miss other errors.
I have tried setting the language to 0 on the product. I have also tried setting the default language on the files themselves. There is more language related markup I tried but I didn't have any luck.
In the xml have included only the two files that are causing the error. As well as any supporting xml incase it is of interest.
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="MyProject" Language="1033" Version="1.0.0.0" Manufacturer="My Company" UpgradeCode="8156a540-97a9-4d3d-b345-9a6d8b833be9">
<Package InstallerVersion="200" InstallScope="perMachine" Platform="x86"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate/>
<Property Id="INSTALLLOCATION" Value="C:\"/>
<SetDirectory Action="SetInstallDir" Id="INSTALLDIR" Value="[INSTALLLOCATION]"/>
<Feature Id="ProductFeature" Title="MyProject" >
<ComponentGroupRef Id="Run32Components" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR">
<Directory Id="RRSDIR" Name="RRS">
<Directory Id="RUN32DIR" Name="RUN32">
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="Run32Components" Directory="RUN32DIR">
<Component Id="PICS2.DLL_Component" Guid="{855DFCC8-50B1-4213-81BA-68878EB31486}">
<File Id="PICS2.dll" Name="PICS.dll" Source="RUN32\PICS2.DLL" />
</Component>
<Component Id="PICSCCRW.DLL_Component" Guid="{A1859D86-1556-497D-8254-118823BF92FB}">
<File Id="PICSCCRW.DLL" Name="PICSCCRW.DLL" Source="RUN32\PICSCCRW.DLL"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
16-Bit Windows Modules: These two DLL files appear to be 16-bit Windows modules, and as such the language set seems to be a code page
and not a language code at all. I will forward to the WiX guys. Just ignore the whole problem I would say, should be fine - barring the madness of installing 16-bit components :-).
Leaving the below for future reference - just in case. Real answer
ends here.
Preliminary Links: While at it, let me lob you some links to related, pre-existing answers. I assume you have found at least one of them already:
wix installer ice03 Invalid Language Id.
Wix toolset license agreement multi-languages issue
As seen in the latter answer you might have a session toying with code pages for the whole package. There are probably better fixes than that though.
Ad-Hoc Sample: Always impossible to add something that you haven't tested and have it work, but just so it is clearer without compiler variables, LCIDs set in Product and Package elements:
<Product Id="*" Name="MyApp" Language="1041" Version="1.0.0"
Manufacturer="MyCompany" UpgradeCode="PUT-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"
Languages="1041" SummaryCodepage="932" />
LCID:
LCID
VbsEdit LCID Chart
CodePage:
Creating a Database with a Neutral Code Page
https://en.wikipedia.org/wiki/Code_page
https://en.wikipedia.org/wiki/Windows_code_page
Other Links:
wix incorrect font used during installation on Windows XP

How can i identify the current logon user in Wix toolset?

I'm trying to build an installer with Wix and i have to put a file in the Startup folder. I already found out how to build the path to the startup folder but i can't find any variabile that can identify the current user.
That's what i have done for now and it works but the part with the name of the user just creates a new directory with that name
There are a couple of things probably wrong with your idea:
You shouldn't need to build that entire directory tree to get to the StartupFolder because there is already a standard Windows Installer property named StartupFolder. This is already the path to the current user's startup folder so it's not clear why you need the value of LogonUser.
Properties are resolved by placing them in square brackets, so in the general case you'd use [LogonUser], but directory names in the Directory table are not marked as Formatted type, so calling a directory [LogonUser] won't work. You'd need to set another public property to the value of [LogonUser] and then use that property as a directory name. However, I think point 1. may be all you need, and your directory tree isn't clear about your intent.
Run on Startup
Normally you would put a shortcut to a file in the startup folder, and not an actual file. You do so by refering to the built-in Windows Installer Property StartupFolder as shown in the mockup-sample below (and as stated by Phil).
In the realm of alternatives, there are many ways to schedule something to start with Windows. What type of file is this and what does it do? In case you are interested, you can see a number of ways used to start something on login or boot by running AutoRuns (from SysInternals). There is a shocking array of possibilities (small digression).
Very often you can run things as services or scheduled tasks, rather than using other startup features. Generally services for features that need to run continuously, and scheduled tasks for stuff that needs to run every now and then. I think most people want to avoid too many things running on login - if they are not really necessary. I find the startup folder "clunky" - and also prone to user interference as well.
Self-Repair and the Startup Folder
This Experts-Exchange article describes a case when self-repair was triggered after deleting a startup folder entry (search for "startup" to find the section).
Frankly I am a bit surprised at the described scenario. When a shortcut is deleted, it should not come back automatically easily, since it is generally not the key path of its hosting component. Still, something to check when you test your MSI (delete the shortcut and then launch your app directly - if there is a shortcut to do so). If you see the problem, please let us know.
If I were to guess what really happened, they might have installed an actual file into the shortcut folder and set it as the key path (which is what it seems you are trying to do as well). Then they have put this in the same feature hierarchy as an advertised shortcut - the same feature or the top feature of the application, or a parent feature - causing self-repair to always be invoked when the advertised shortcut is invoked, and the missing file is detected in the Startup folder and self-repair ensues.
Digression: a sizeable digression, the important point is to please check this for your setup! This kind of problem really aggravate your users - the cause of it tends to elude their support guys.
Mockup WiX Sample
Here is one sample for how to install a shortcut to the Startup folder. Note that the Startup folder redirects depending on whether the setup is installed per-user or per-machine, as documented on MSDN: StartupFolder.
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Startup Shortcut" Manufacturer="Someone" Version="0.0.1"
Language="1033" UpgradeCode="PUT-GUID-HERE">
<Package InstallScope="perMachine" Compressed="yes" />
<Media Id="1" Cabinet="my.cab" EmbedCab="yes" />
<UIRef Id="WixUI_Mondo" /> <!-- Just include a default setup GUI -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="MyCompany" Name="Company">
<Directory Id="MyAPP" Name="MyApp">
<Component Feature="MyFeature">
<File Source="MyApp.exe" />
<!-- Set Advertise="no" to avoid advertised shortcut -->
<Shortcut Id="MyApp" Directory="StartupFolder" Name="MyApp"
Advertise="yes" />
</Component>
</Directory>
<Directory Id="StartupFolder" />
</Directory>
</Directory>
</Directory>
<Feature Id="MyFeature" Absent="disallow" />
<Property Id="MSIFASTINSTALL" Value="7" /> <!-- Tweak to install faster -->
</Product>
</Wix>
This should be a property set automatically in the installer at run time, LogonUser.

Wix Installer Going to Wrong Path on Command Line with Admin Privilege

I built a simple installer in Wix which will place a couple of data files in a specific folder in a preexisting product installation so that the user doesn't need to know anything about the product's installation in order to update their data files. The product stores its installation path in an environment variable (ENVVAR) which I'm using here to calculate the path of its NewData subfolder.
When I double-click the .msi or run it from the command line (msiexec /i filename.msi) it works perfectly and the files show up in C:\ProductPath\NewData. However, if it's installed with elevated privileges (msiexec /a filename.msi) the files go to the root of D:\ (which isn't even the same drive the product is installed on.)
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<?include InstallVariables.wxi ?>
<Product Id="*"
Name="Product Name"
Manufacturer="My Company"
Version="$(var.Version)"
UpgradeCode="guidgoeshere"
Language="1033">
<Package Description="Description $(var.Version)" Comments="Install package for my product."
InstallerVersion="300" Compressed="yes" InstallScope="perMachine"/>
<Media Id="1" Cabinet="Cabname.cab" EmbedCab="yes" CompressionLevel="high"/>
<SetDirectory Id="PATHMAP" Value="[%ENVVAR]\NewData" Sequence="first" />
<!-- Describe the folder layout here. -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="PATHMAP" FileSource="..\New Files">
<Component Id="File1" Guid="guidgoeshere">
<RemoveFile Id="Remove_File1File" Name="$(var.File1Pattern)" On="both" />
<File Id="File1File" Name="$(var.File1)" Vital="yes" KeyPath="yes" />
</Component>
<Component Id="File2" Guid="guidgoeshere">
<RemoveFile Id="Remove_File2File" Name="$(var.File2Pattern)" On="both" />
<File Id="File2File" Name="$(var.File2)" Vital="yes" KeyPath="yes" />
</Component>
</Directory>
</Directory>
<Feature Id="FeatureId" Title="New Files for a Feature" Level="1" >
<ComponentRef Id="File1"/>
<ComponentRef Id="File2"/>
</Feature>
</Product>
</Wix>
Note that the file removal in the components is intentional; if there is an existing version of either file (which may have a slightly different file name -- not my choice) I want to remove and replace it. The patterns used to do so are in the include file and are working properly.
The command line: msiexec.exe /a filename.msi will not trigger installation with elevated privileges, but rather an administrative installation. Follow the link for a description - it is important that you do for a complete description. Essentially an administrative installation is just an extraction of embedded files in the MSI to make a network installation image from where people can run a regular installation of the MSI (better explained in the linked answer above) - administrative installations don't install anything at all - it is a mere extraction.
You should be able to control the output directory of the administrative installation by providing a TARGETDIR like this: msiexec.exe /a filename.msi TARGETDIR=C:\MyOutputFolder\. Your MSI is probably lacking a basic GUI to show the administrative installation's dialog sequence - which makes the extraction happen without any parameters specified (hence you output to the largest drive on the box by default). You might want to consider linking a standard dialog set such as <UIRef Id="WixUI_Mondo" /> for your MSI. You can see a step-by-step description of how to do this here: WiX installer msi not installing the Winform app created with Visual Studio 2017. This will give your setup basic, standard GUI for both regular installation and administrative installation. Very useful I think - you should also set your own license agreement - I have updated the linked answer to include that.
I think this is the end of the answer for you. Installing with /a isn't installation with elevated rights - essentially - it is just an extraction of files. But do link in that default GUI to make your MSI more standard and better overall.
A couple of comments on the environment variable approach. I have never stored anything like that in environment variables. I usually just write to my own location in HKLM and read back from there either via a custom action or using MSI's built in search feature (preferably the latter - it is much better to rely on built-in MSI features. I am a little sloppy with read-only custom actions at times, but very much against read-write custom actions. You can see why here: Why is it a good idea to limit the use of custom actions in my WiX / MSI setups? - a digression I guess). WiX can easily define these searches and set the search result to your property: Define Searches Using Variables.
Maybe a quick link to "The WiX toolset's "Remember Property" pattern" by Rob Mensching (WiX creator). This is quite old now, there may be a new, smarter way to do this that I am not aware of yet.
If I were you, I would rather download these updated files from the network rather than deploy them like this into a "data folder" using Windows Installer. Deployment of user data files has always been problematic with MSI with its complex file overwrite rules and "quirks". Though perhaps not entirely related to your use case, here is a description of other approaches you can use to deploy data files for your application - perhaps in a more reliable fashion: Create folder and file on Current user profile, from Admin Profile. Maybe have a quick skim at least.
There are two types of environment variables: user environment variables (set for each user) and system environment variables (set for everyone).
By default, a child process inherits the environment variables of its parent process. Programs started by the command processor inherit the command processor's environment variables.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx
Probably, you can check machine users and if product is installed for all users point to system environment variable in Local Machine.

Wix creating multilanguage msi

recently I'm working on creating a multilanguage wix msi package for my team. I searched the localization on Google and also on stackoverflow for quite some time and finally found something to follow:http://www.geektieguy.com/2010/03/13/create-a-multi-lingual-multi-language-msi-using-wix-and-custom-build-scripts/. Currently I just added 2 language support: english and simplified Chinese to check if this approach works for me. The main wxs front part is something like this:
<Product Id="B5CB3C6A-A8ED-4308-8ADE-17729FE1FB23" Name="MyProduct" Language="!(loc.LANG)" Codepage="UTF-8" Version="11.51.0027" Manufacturer="My Company" UpgradeCode="D42070C3-43CB-4E2B-9B96-2F8D84A6C8A8">
<Package InstallerVersion="200" Compressed="yes" Languages="1033,2052" InstallPrivileges="elevated" InstallScope="perMachine" />
And for the Language attribute of the Product I'm getting value from the localization wxl file, I've 2 files now, one is en-US.wxl, another is zh-CN.wxl,
in en-US.wxl: 1033
in zh-CN.wxl 2052
I also set the corresponding codepage in 2 wxl files, setting en-US codepage to 1252 and zh-CN to 936.
After building the project in VS, I got 2 msi, one in en-US folder and another in zh-CN folder, and I use the following commands to create the multilanguage msi:
cscript WiLangId.vbs zh-CN\MyProduct.msi Product 2052
Msitrans.exe -g en-US\MyProduct.msi zh-CN\MyProduct.msi zh-CN.mst
cscript WiSubStg.vbs en-US\MyProduct.msi zh-CN.mst 2052
cscript WiSubStg.vbs en-US\MyProduct.msi
And performing the commands above in cmd, I copied the final msi onto a Chinese win7 system to try, the problem is after I double clicking the msi to install, the first UI dialog is still in English but shortly it became Chinese, I'm sorry that I couldn't post the screenshot here because stackoverflow requires 10 reputations to be able to post images, but the words on the first Dialog I saw is "Preparing to install...." and a button on the bottom right "Cancel" and then after 2-3 seconds the UI became Chinese. Did anyone come up with this problem before?
Windows System restore point is created by default (if enabled system-wide) at the start of a MSI install. This system restore point seems to occur before locale transform and cause the behavior you observed.
You can disable it by setting MSIFASTINSTALL property to 1 or any value that includes it (e.g. 5 if you also want to reduce the amount of progress messages)
<Property Hidden="yes" Id="MSIFASTINSTALL" Value="1" />
For example in your .wxs file:
<?xml version="1.0" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>
<Product Id="XXX" Name="XXX" Language='!(loc.LANG)' Codepage='0'
Version="XXX" Manufacturer="XXX"
UpgradeCode="XXX">
<Product Id="B5CB3C6A-A8ED-4308-8ADE-17729FE1FB23" Name="MyProduct" Language="!(loc.LANG)" Codepage="UTF-8" Version="11.51.0027" Manufacturer="My Company" UpgradeCode="D42070C3-43CB-4E2B-9B96-2F8D84A6C8A8">
<Package InstallerVersion="200" Compressed="yes" Languages="1033,2052" InstallPrivileges="elevated" InstallScope="perMachine" />
<!-- Disable System Restore point creation for this MSI (faster installation) -->
<Property Hidden="yes" Id="MSIFASTINSTALL" Value="1" />
<!-- Rest of your setup ... -->
</Product>
</Wix>
You can read about MSIFASTINSTALL on Microsoft Windows docs

WiX bootstrapper that only shows the package Dialogs or atleast one that doesn't require the license approval

I have a project that I am creating an installer for. I have the msi created that will do the install but I also need to install some pre-reqs (.NET 4.0 and VSTO client tools or whatever they are called)
From what I can tell I need to use a bootstrapper and while it seems to work I really don't want the default dialogs that make me approve the license. I would like to skip that completely. (If I could hide the bootstrapper that would be fine but just having an "Install" button without the EULA would be ok).
Here is the xml I am currently using.
<?xml version="1.0" encoding="UTF-8"?>
<WixVariable Id="WixStdbaLogo" Value="logo.png" />
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
</BootstrapperApplicationRef>
<Chain>
<!-- TODO: Define the list of chained packages. -->
<PackageGroupRef Id="NetFx40Web"/>
<MsiPackage SourceFile="TestRibbonLocationInstaller.msi" DisplayInternalUI="yes" />
</Chain>
</Bundle>
So from what I can tell I need to basically create a custom bootstrap application for this that I then reference as the bootstrapperapplication. By doing this I will be able to better control the UI (Basically hide it).
Is this thought process correct?