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
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.
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 :-).
I currently have a working .msi built with WiX that has a user interface I'm quite happy with. The only thing missing is to detect for missing .NET 4.5 and either:
Install it using an embedded web setup, or
Direct the user to the .NET 4.5 download
The previous Setup and Deployment project I was using simply added it as a LaunchCondition with a URL and that worked well enough.
How can I add this to the WiX installer without resorting to a bootstrapper. From what I can tell using a bootstrapper like burn would require re-implementing a new user interface, likewise a tool like dotNetInstaller would also introduce a new UI.
If I can have the bootstrapper not implement it's own UI but trigger the .NET installation then open the msi's current user interface that would also work for me.
This is the code I ended up using... hasn't been through full testing yet!
Product.wxs:
...
<!-- custom actions -->
<InstallUISequence> <!-- .NET dialog runs only in UI mode and we skip it on the wrong platform so platform condition test is triggered later -->
<?if $(var.Platform) = x64 ?>
<Custom Action="InstallCA" Before="LaunchConditions">(NOT REMOVE~="ALL") AND NOT (Installed OR NETFRAMEWORK45) AND VersionNT64</Custom>
<?elseif $(var.Platform) = x86 ?>
<Custom Action="InstallCA" Before="LaunchConditions">(NOT REMOVE~="ALL") AND NOT (Installed OR NETFRAMEWORK45) AND NOT VersionNT64</Custom>
<?endif?>
</InstallUISequence>
</Product> <!-- end product -->
<Fragment>
<Binary Id="WiXCustomActions" SourceFile="$(var.WiXCustomActions.TargetDir)$(var.WiXCustomActions.TargetName).CA.dll" />
<CustomAction Id="InstallCA" BinaryKey="WiXCustomActions" DllEntry="DotNetCheck" Execute="firstSequence" />
</Fragment>
And the custom action (in a C# class library):
[CustomAction]
public static ActionResult DotNetCheck(Session session)
{
try
{
MessageBoxResult result = System.Windows.MessageBox.Show(
"This application requires that .NET Framework 4.5 is installed." + Environment.NewLine
+ "Would you like to open the Microsoft download page for" + Environment.NewLine + ".NET Framework 4.5?",
".NET Framework 4.5 is missing",
MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.No, MessageBoxOptions.DefaultDesktopOnly);
switch (result)
{
case MessageBoxResult.Yes:
System.Diagnostics.Process.Start("http://go.microsoft.com/fwlink/p/?LinkId=245484");
break;
} //else just finish
}
catch (Exception ex)
{
session.Log("Error. " + ex.Message);
System.Windows.MessageBox.Show("Error:" + ex.Message);
}
return ActionResult.SkipRemainingActions;
}
It works good enough for me...
I also wanted to keep the UI from the MSI so I added this code to start an exe installer for hardware keys. I know it goes against MSI Best Practices but this is the only one I intend on breaking. Hope this helps.
<Property Id="WixShellExecTarget" Value="[#myapplication.exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
I then ran the custom action from a button click. You could spawn an error dialog with a download button on it and link it via that. Not very elegant at all but it works for me and my company as a work around..:)
EDIT: you could also use this code from a button click to launch the URL for the download, the Value attribute having the full hyperlink.
And one important things, when you will be creating this DLL lib
And the custom action (in a C# class library):
Need to add next References:
using WixSharp
using Microsoft.Deployment.WindowsInstaller
using System.Windows.Forms
also replace "MessegeBoxResult" to "DialogResult" and MessegeBox should get from class System.Windows.Forms
I have an NT service that has some perf counters. When I deploy the service using installutil, the perf counters and the service install fine. When I deploy using my msi, that uses ServiceInstall, the service shows up, but the perf counters don't get installed.
I always just assumed that ServiceInstall ran installutil under the covers. Is there some critical difference that would prevent me from installing perf counters?
Wix segment
<ServiceInstall Id='ServiceInstall' ErrorControl='ignore' Type='ownProcess' DisplayName='Service' Description='service' Name='Service' Start='auto' Account='[SERVICEACCOUNT]' Password='[SERVICEACCOUNTPASSWORD]' />
<ServiceControl Id='Service' Remove='uninstall' Name='Service' Start='install' Stop='both' Wait='yes' />
Perf counter install
[RunInstallerAttribute(true)]
[RegistryPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
[EnvironmentPermissionAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)]
public sealed class CountersInstaller : Installer
{
public CountersInstaller()
{
Installers.AddRange(Counters.Instance.PerformanceCounterInstallers());
}
}
No, your assumption is not correct. The ServiceInstall does not call InstallUtil under the hood for installing performance counters. Using InstallUtil is generally treated as a bad practice.
Instead, take a look at PerformanceCategory and PerformanceCounter elements. Of course, this will require some coding to transform what you do now with C# into declarative XML form.
I'm trying to create a custom action for my Wix install, and it's just not working, and I'm unsure why.
Here's the bit in the appropriate Wix File:
<Binary Id="INSTALLERHELPER" SourceFile=".\Lib\InstallerHelper.dll" />
<CustomAction Id="HelperAction" BinaryKey="INSTALLERHELPER" DllEntry="CustomAction1" Execute="immediate" />
Here's the full class file for my custom action:
using Microsoft.Deployment.WindowsInstaller;
namespace InstallerHelper
{
public class CustomActions
{
[CustomAction]
public static ActionResult CustomAction1(Session session)
{
session.Log("Begin CustomAction1");
return ActionResult.Success;
}
}
}
The action is run by a button press in the UI (for now):
<Control Id="Next" Type="PushButton" X="248" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" >
<Publish Event="DoAction" Value="HelperAction">1</Publish>
</Control>
When I run the MSI, I get this error in the log:
MSI (c) (08:5C) [10:08:36:978]: Connected to service for CA interface.
MSI (c) (08:4C) [10:08:37:030]: Note: 1: 1723 2: SQLHelperAction 3: CustomAction1 4: C:\Users\NATHAN~1.TYL\AppData\Local\Temp\MSI684F.tmp
Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action SQLHelperAction, entry: CustomAction1, library: C:\Users\NATHAN~1.TYL\AppData\Local\Temp\MSI684F.tmp
MSI (c) (08:4C) [10:08:38:501]: Product: SessionWorks :: Judge Edition -- Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action SQLHelperAction, entry: CustomAction1, library: C:\Users\NATHAN~1.TYL\AppData\Local\Temp\MSI684F.tmp
Action ended 10:08:38: SQLHelperAction. Return value 3.
DEBUG: Error 2896: Executing action SQLHelperAction failed.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2896. The arguments are: SQLHelperAction, ,
Neither of the two error codes or messages it gives me is enough to tell me what's wrong. Or perhaps I'm just not understanding what they're saying is wrong.
At first I thought it might be because I was using Wix 3.5, so just to be sure I tried using Wix 3.0, but I get the same error.
Any ideas on what I'm doing wrong?
For your custom action assembly you need a config file and set the useLegacyV2RuntimeActivationPolicy attribute to true. Make sure you name your config file CustomAction.config. If you don't, it won't work. I am assuming you are running on the .NET 4 Framework.
See here for more info. Also, as AntonyW already pointed out, fuslogvw.exe is very helpful in this scenario.
instead of referencing the .dll reference the .CA.dll, it worked for me.
Custom Actions launched via DoAction are not able to write to the log file.
This confused me as well, when I first started using WiX.
If you want to see what is going on, you can use System.Diagnostics.Debugger.Launch() at the start of the Custom Action. This will prompt you to attach Visual Studio to the process so you can debug it.
For me, it was my CustomAction DllEntry did not match my method name. i.e.
<CustomAction Id="CheckingPID" BinaryKey="CheckPID.CA" DllEntry="BadValue" />
public static ActionResult CheckPID(Session session)
This error comes when you have installer project configuration/platform set to debug/x64 and custom action project configuration/platform set to debug/x86 repectively.
Correct the platform setting to build the projects for same platform
In my case changing platorm solved the issue.
Thanks
Yogesh
One more possible answer - you may have specified the right CA DLL, and specified the right method, but if the method is not decorated with [CustomAction] you will receive that error.
Have you tried changing the runtime library settings on the custom action DLL? The debug mode options /MDd and /MtD require debug versions of the C++ runtime in particular, which are not available on production machines (there is no redistributable license for them). If you use the /MD compiler option you might also need to install the Visual Studio C++ runtime version that you require on the users' machines, there is a merge module for that: C++ Redistributable package with WIX.