I have a service component installed twice in one of my previous releases.
<Component Id="MyServiceWin7" Guid="{GUID_WIN7}">
<File Id="mysvc_Win7"
Name="mysvc.exe"
Source=mysvc.exe"
KeyPath = "yes"/>
<ServiceControl Id="MYSVC_Win7"
Name="MYSVC"
Remove="uninstall"
Start="install"
Stop="both"
Wait="no" />
<ServiceInstall Id="My_Svc_Win7"
Name="MYSVC"
DisplayName="MYSVC"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
LoadOrderGroup=""
Description="My service">
</component>
<Component Id="MyServiceWin8" Guid="{GUID_WIN8}">
<File Id="mysvc_Win8"
Name="mysvc.exe"
Source=mysvc.exe"
KeyPath = "yes"/>
<ServiceControl Id="MYSVC_Win8"
Name="MYSVC"
Remove="uninstall"
Start="install"
Stop="both"
Wait="no" />
<ServiceInstall Id="My_Svc_Win8"
Name="MYSVC"
DisplayName="MYSVC"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
LoadOrderGroup=""
Description="My service">
</component>
So there will be two instances of the MYSVC component. Both are mapping to MYSVC.exe.
I missed the OS version condition check in the previous release.
It runs successfully.
I am thinking to delete the dummy additional COMPONENT (GUID_Win7 or GUID_WIN8) in the next update.
How I can delete it, do I need to write a custom action?
Any help would be appreciated.
EDIT::
Please find answers,
mysvc is having some third party lib dependancy os specific Win7 and Win8, it works means it installed successfully if we check sc qc mysvc I get service created and mysvc.exe is mapped to service binpath
yes these two service components targets same destinationand there is only one component when I do sc query mysvc
No there only one entry of service. mysvc.exe is win8 version on disk.
Thanks for suggestions, that breaking link.
Currently I have %ProgramFiles%\MyApp\mysvc.exe common path for both win 7 and win8.
So my question if create new common path to break previous link.
ProgramFiles%\MyApp\mysvc\mysvc.exe [[NEW_GUID1]] for win7
ProgramFiles%\MyApp\mysvc\mysvc.exe [[NEW_GUID2]] for win8
Components with [[OLD_GUID1]] , [[OLD_GUID2]] will be on system forever
until my product is uninstalled, so cant we just delete components with [[OLD_GUID1]], [[OLD_GUID2]] to clean stale(non functional) components
Thanks
Some Questions:
First of all, can we ask why you decided to install the service in two flavors? Does this mean that the service has different binaries for Win7 and Win8? If so, then it is unclear why you say it works as it stands.
Do these service components target two different installation locations so they both run side-by-side, or do you target the same target destination with both components? (so there is only one instance of the file after installation).
Are there two entries in the list of services on the box after installation? If you target the same location with both components, what file version of mysvc.exe made it onto the disk? (if they are different).
I wrote the below before the above questions. Please update your question with the answers to the questions. The below might be irrellevant - we need more information.
Sins of The Past: If you have installed the same file twice with two different component GUIDs in the previous version then this is wrong and I would recommend you "break the link" to the sins of the past by setting two new component GUIDs for the new release and crucially: set a new absolute installation location for each component (do not target the same absolute key path with two different GUIDs! - conditions or not).
The idea is to de-couple the old and new versions so that you start with a clean(er) slate.
Something like:
Comp 1: {77777777-7777-7777-7777-777777777777}, [ProgramFilesFolder]My App\Win7\mysvc.exe
Comp 2: {42424242-4242-4242-4242-424242424242}, [ProgramFilesFolder]My App\Win8\mysvc.exe
Personally I would avoid the Windows version number and maybe use something else. How about a year?
Comp 1: {77777777-7777-7777-7777-777777777777}, [ProgramFilesFolder]My App\2007\mysvc.exe
Comp 2: {42424242-4242-4242-4242-424242424242}, [ProgramFilesFolder]My App\2014\mysvc.exe
Just to not hard code a misleading value if the Win8 version runs on Win10 for example.
N.B!: Note that the above, sample GUIDs are well-known and dysfunctional GUIDs and
should not be copied and used! This is of high cruciality :-).
Related
I am trying to install Microsoft Access Runtime 2013 32-Bit silently using quiet property, but still it is showing the Installation UI window and asking to accept EULA. Earlier I was using Access Database Engine 2007 which was getting installed silently with quiet command. What am I missing? I am using below code to install it silently:
<ExePackage DisplayName="Microsoft Access Runtime 2013"
SourceFile="..\Prerequisites\Microsoft Access x86 Runtime 2013\AccessRuntime_x86_en-us.exe"
InstallCommand="/quiet"
InstallCondition="NOT ACCESS_ENGINE=5"
Permanent="yes"
Compressed ="yes"
/>
Please read the following tips from itninja.com (formerly appdeploy.com):
https://www.itninja.com/software/microsoft/access-runtime/2013-14
https://www.itninja.com/question/packaging-access-runtime-2013
Essentially:
Extract files using AccessRuntime_x86_en-us.exe /extract:ExtractedFiles.
Create a config.xml as described in the links above. Let me just duplicate it here in case the links go dead. And obviously update the paths for your purpose and for your environment:
<Configuration Product="AccessRT">
<Display Level="None" CompletionNotice="no" SuppressModal="yes" AcceptEula="yes" />
<Logging Type="standard" Path="C:\Windows\Temp\" Template="Microsoft_Access_2013_Runtime_Setup(*).log" />
<COMPANYNAME Value="Company Name" />
<Setting Id="SETUP_REBOOT" Value="Never" />
</Configuration>
Install with setup.exe /config config.xml.
This question already has an answer here:
UPGRADINGPRODUCTCODE condition not working in wixui_install.wxs in library
(1 answer)
Closed 7 years ago.
I have an application that needs to know if it has been upgraded. So I thought of writing a registry key with the installer, which then could be read from the application. I tried to achieve this by adding the following component to the installer:
<Component Id ="Registry_IsUpgraded">
<Condition>Installed AND UPGRADINGPRODUCTCODE</Condition>
<RegistryValue Id="RegKey_IsUpgraded" Root="HKLM"
Key="SOFTWARE\Microsoft\Office\Excel\AddIns\websmsExcelAddIn"
Name="IsUpgraded" Value="yes"
Type="string" />
</Component>
However, registry key is not written during the upgrade. In the msi log I found this line:
Component: Registry_IsUpgraded; Installed: Absent; Request: Local; Action: Null
I suppose Action: Null means that the component will not be installed, since Action for other Components that are installed during the upgrade is Local.
But why is this and why is my registry key not written? Is there maybe a better/easier way to tell my application that it has been upgraded?
Installed and UPGRADINGPRODUCTCODE is always going to evaluate to false because during a major upgrade (indicated by UPGRADINGPRODUCTCODE) the new product is by definition not yet Installed.
I assume your application needs to do something on first run after each upgrade, yes? If so, just write the ProductCode property to the registry value and then in your application code trigger an event when it detects the value has changed. This will simplify your installer requirements.
As part of an WiX-based installer I have the following component with a User element (besides other components with File, ServiceInstall and ServiceControl elements):
<Component Id="cmpServiceUser" Directory="TARGETDIR" Guid="PUT-GUID-HERE">
<util:User
Id="ServiceUser"
Name="[ProductName]"
Password="[ServiceUserPassword]"
PasswordNeverExpires="yes"
LogonAsService="yes"
CreateUser="yes"
UpdateIfExists="yes"
RemoveOnUninstall="yes"
/>
</Component>
I have decided to go the only-major-upgrades way and placed the following element inside the Product:
<MajorUpgrade
Schedule="afterInstallInitialize"
DowngradeErrorMessage="A newer version of [ProductName] is already installed."
/>
The first installation of the product works as expected. During a major upgrade, I would have expected the user to be first removed (during RemoveExistingProducts) and later being created again. But it behaves different: The user is really removed nearly at the end of the installation - after the service for example has been restarted again (Process Explorer can still tell me the service's user name but not the SID any more - as the service's user was removed after the service was started).
After many hours of dissecting various installation logs I have turned to peek into the sources of the UtilExtension and probably found an explanation in scauser.cpp (slightly reformatted for better SO-readability):
// Schedule the removal because the user exists and we don't have any flags set
// that say, don't remove the user on uninstall.
//
// Note: We can't rollback the removal of a user which is why RemoveUser is a
// commit CustomAction.
So I guess this late removal of the user really belongs to the RemoveExistingProducts action in this case.
Thanks for reading this far - now the question: Is it possible to use util:User#RemoveOnUninstall in collaboration with a major upgrade strategy?
I am trying to install windows services using WIX. The windows services are installing fine and if I check inside Service Manager I am able to see that my services are installed and are trying to start as shown below:
After 3 to 4 minutes I am getting error sufficient privileges required. Please see the image for the error message:
If I run my windows services setup manually then it's installing fine without any problem in starting up. What I am doing wrong can anyone help?
Following is the code that I am using:
public ProjectInstaller()
{this.ServiceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
this.ServiceInstaller = new System.ServiceProcess.ServiceInstaller();
//
// ServiceProcessInstaller
//
this.ServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalService;
this.ServiceProcessInstaller.Password = null;
this.ServiceProcessInstaller.Username = null;
//
// ServiceInstaller
//
this.ServiceInstaller.ServiceName = "Service";
this.ServiceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
Following is my WIX code:
<File Id='SetupService' Name='SetupService' DiskId='1' Source='setup.exe' KeyPath='yes'/>
<ServiceInstall Id="ServiceInstaller" Type="ownProcess" Name="SetupService" DisplayName="DataLogsetup" Description="Service" Start="auto" Account="[SERVICEACCOUNT]" Password="[SERVICEPASSWORD]" ErrorControl="normal"/>
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="SetupService" Wait="yes" />
I have also tried to pass in [LocalService] in the Account, but still I am getting the same error. Is there anyway I can install my service using WIX?
I see several reasons which may lead to failure here:
You are not calling
Installers.Add(this.ServiceInstaller);
Installers.Add(this.ServiceProcessInstaller);
at the end of your method. The Installers.Add(..) line should actually add the service to service table. See the example at the end of this page
As far as I know, Installer classes are not supported in WIX, Custom Actions are used instead. How do you call your code from WIX?
WIX has a <ServiceInstall> element for installing services. Although not allmighty, this element is very powerful and the preferred method to install Windows Services. See Installing and starting a Windows Service using WiX
One of our MSI's has started failing with Error 2902. It'll get most of the way through the installation, pop an error box, and then back out the install. We haven't made any major changes to the installer since the last working version.
Running msiexec with logging turned on gives a more informative message:
Action 17:21:22: RegisterProduct. Registering product
Error 2902: Operation ixoFileCopy called out of sequence
This comes immediately after the "WriteRegistryValues" section. Does anyone know what causes the call to ixoFileCopy? I'm guessing the resolution will involve changing the sequence of the "RegisterProduct" step, but I'm not sure what it should proceed.
Thanks for any help!
It turns out that in our case this was happening due to a data file getting too big for MSI to handle without chunking the cab. This thread mentions the issue and one possible workaround.
I had the same error.
Apparently, there were files missing or corrupted (network error?). The problem has been solved after copying the whole folder again.
I've also seen this error when components are provided with blank guids.
e.g.
<Component Id="cmp_MyFailingComponent" Guid="">
<File Id="f_myFile"
Assembly=".net"
Source="C:\Program Files\MyFile.dll"
KeyPath="yes"/>
</Component>
I've seen this error when some of the database column fields are longer than the column width.
I had converted an MSI into an InstallShield project, made a few additions, and built a new MSI - it built without any errors. Installation then failed with error 2902.
The components that failed had component names longer than the allowed 72 characters. (see Component table) The original MSI worked fine despite having the long names, but I guess they caused InstallShield to improperly build the MSI somehow. Not InstallShield's fault, although I do think it should have raised an error during the build.