I have developed an msi setup using WIX which consists of a desktop application as well as a windows service and both are running on C# .Net 3.5 framework. My windows service starts only when any user logs into the system which triggers the desktop application to start. The windows service is made to run as Local System. The msi setup is getting installed successfully at Win-8, Win-7 and Windows-XP but showing "File In Use" message while doing uninstallation even the service is not removed from the SCM. I have given the below codes at the OnStop() method of the service and inside the WIX page respectively.
onStop() method:
Process[] workers = Process.GetProcessesByName("filename");
workers[0].WaitForExit(1000);
workers[0].Kill();
workers[0].Dispose();
workers[0].Close();
Product.wxs inside WIX:
<ServiceInstall Id="ServiceInstaller" Name="Servicename"
DisplayName="service display name" Description="service description"
Start="auto" Account="LocalSystem" ErrorControl="normal"
Type="ownProcess"></ServiceInstall>
<ServiceControl Id="ServiceInstallerControl" Name="Servicename"
Start="install" Stop="both" Remove="uninstall" Wait="yes" />
The service is not removed from the SCM at all and the below popup message is displaying at the time of uninstallation process.
I have worked around with the WIX to solve the problem but unable to do so.
Any kind of help in this regard will be highly appreciated.
I'd recommend you to create custom action that handles the uninstall.You can create a batch file with the uninstall details , and then simply execute the batch file from the custom action( as a process).Its good practice to create installation and uninstall batch files with your service.
Related
The line of code that throws the error is:
new ToastContentBuilder()
.AddText("Title of notification")
.AddText("Body of notification")
.Show();
The program is a Windows service made in C#, installed using a Wix installer. ToastContentBuilder comes from the Microsoft.Toolkit.Uwp.Notifications namespace. In Product.wxs, I have set the ServiceInstall tag as such:
<SeviceInstall Id="ServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="MyProcessName"
DisplayName="My Process Name"
Description="My process description."
Start="auto"
Account="LocalSystem"
ErrorControl="normal"
Arguments=""
Interactive="yes" />
In the Services viewer in Windows, I have checked the properties of the process, and it is logged on as a Local System account, and the "Allow service to interact with desktop" box is checked.
I am aware of a similar question, but that question is unanswered and is seemingly not a service installed using Wix, so it is of little use.
I would appreciate any leads. I am not very familiar with Wix so something in Product.wxs may be at fault.
I've never tried to send a toast message from a windows service. I have sent toast messages from tray apps and scheduled tasks running as the user.
To have click events in the toast you have to create an app with a shortcut in the start menu like this:
<Shortcut Id="sc1" Name="Some App" Directory="ProgramMenuFolder" Description="Some App">
<!--AUMID-->
<ShortcutProperty Key="System.AppUserModel.ID" Value="WindowsNotifications.SomeApp" />
<!--COM CLSID, specifying which CLSID to activate when toast clicked-->
<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="guid-used-in-code" />
</Shortcut>
In your code you have to implement
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(INotificationActivationCallback))]
[Guid("guid-used-in-code"), ComVisible(true)]
and
protected override void OnStartup(StartupEventArgs e)
{
// Register AUMID, COM server, and activator
DesktopNotificationManagerCompat.RegisterAumidAndComServer<MyNotificationActivator>("WindowsNotifications.SomeApp");
DesktopNotificationManagerCompat.RegisterActivator<MyNotificationActivator>();
I am trying to launch a full-trust process program from my UWP app. I am using the PackageManager in my full-trust process to locate UWP packages to launch files or links, so I need to run it as an admin.
When I try running the full-trust process, it opens and works properly on my machine (I am running an admin account). However, when I look up the process in the Task Manager, it does not run elevated.
I'm just worried that it may not work on any other machine (non-admin) out there. Here's my code I'm using in Package.appxmanifest, courtesy of Stefan Wick (https://stefanwick.com/2018/10/07/app-elevation-samples-part-3/):
<desktop:Extension Category="windows.fullTrustProcess" Executable="Assets\NitishTest.exe">
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="Parameters" Parameters="parameters" />
</desktop:FullTrustProcess>
</desktop:Extension>
<uap3:Extension Category="windows.appExecutionAlias"
Executable="Assets\NitishTest.exe"
EntryPoint="Windows.FullTrustApplication">
<uap3:AppExecutionAlias>
<desktop:ExecutionAlias Alias="NitishTest.exe" />
</uap3:AppExecutionAlias>
</uap3:Extension>
I am not using a Windows Application Packaging Project, however. Could this be the reason why it's not working properly elevated?
I have a Wix installer where I have a property defined (Product.wxs):
<Property Id="SITEBASE" Value="localhost"/>
<Component Id="ApplicationSettings">
<File Id="ApplicationConfig" Name="MyApplication.exe.config" Source="$(var.Application.TargetPath).config"/>
<util:XmlFile
Id="ApplicatonConfig1"
File="[INSTALLDIR]MyApplication.exe.config"
Action="setValue"
Value="[SITEBASE]"
ElementPath="//MyApp.Properties.Settings/setting[\[]#name='SiteBase'[\]]/value"
Permanent="yes"
Sequence="1" />
<Component Id="ApplicationSettings">
<File Id="ApplicationConfig" Name="MyApplication.exe.config" Source="$(var.Application.TargetPath).config"/>
<util:XmlFile
Id="ApplicatonConfig1"
File="[INSTALLDIR]MyApplication.exe.config"
Action="setValue"
Value="[SITEBASE]"
ElementPath="//MyApp.Properties.Settings/setting[\[]#name='SiteBase'[\]]/value"
Permanent="yes"
Sequence="1" />
My source MyApplication.exe.config has SiteBase = "http://localhost/AnotherValueForTesting"
I have a Dialog where I an set the value for SiteBase (starts off as the value from Property SITEBASE so will display: localhost
If I Install the application as TestUser1, changing localhost to 1.1.1.1 the config file has the entered value (1.1.1.1) and everything is fine. I can reboot and log in using TestUser1 and all is still good.
If I log in as TestUser2, the values for TestUser2 will now have "localhost" (the default for the property)
I can then uninstall, re-install (using the 1.1.1.1 value) and when I log in as TestUser1/2 both have 1.1.1.1.
If I then log in as TestUser3, TestUser3 again has localhost, not 1.1.1.1. I tested with a different value in the app.config to determine that the value is definitely defaulting to what is set for Property Id "SITEBASE" and not the original in app.config
PS: the Package InstallScope="perMachine"
The short answer is that you're probably correct about the installer running again. It's a feature that if you have a file in a user profile directory (that therefore is installed at first only for that user) and then another user uses the app Windows will notice that the file is missing for that user and install it. Sine the application defines the file as being in a user folder it makes sense for all users to want that file also.
If that's not precisely what's happening, it may also be possible that the installed product is getting broken in some way and Windows is repairing it.
Either way, if you look in the Event log there should be MsiInstaller entries that refer to a missing component, quoting the guid that you can look for in your setup. That may help.
Someone on our team found the problem.
App logs had:
Detection of product '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}', feature 'ProductFeature', component '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}' failed. The resource 'HKEY_CURRENT_USER\Software\XXX\YYY\' does not exist.
Detection of product '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}', feature 'ProductFeature' failed during request for component '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'
Beginning a Windows Installer transaction: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Client Process Id: 19300.
Windows Installer reconfigured the product. Product Name: YYY. Product Version: 1.0.0. Product Language: 1033. Manufacturer: XXX. Reconfiguration success or error status: 0.
Product: YYY -- Configuration completed successfully.
Ending a Windows Installer transaction: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Client Process Id: 19300.
installer creates a registry entry under HKCU. Because this is a per-user setting, it doesn't exist for the next user, so an MSI repair is begun.
Changing it to install to HKLM instead of HKCU looks to have fixed the problem
Is it possible to restart a service if setup MSI is cancelled by the user?
There is two scenarios where the MSI has to restart the service.
Stop and update the old service files and then start the service. If service fails to start, replace back the old files and restart the service. [This part is done with rollback]
Restart the service if MSI is cancelled intentionally during setup process.
I have a solution that I can call a CustomAction on cancel and used CMD.EXE to restart a service, but I don't like it. Please suggest any other solution like by using RestartResource or ResourceManager
Code:
<InstallExecuteSequence >
<RemoveExistingProducts
After="InstallInitialize"/>
<Custom Action="RenameFileOnCancel" OnExit="cancel">1</Custom>
</InstallExecuteSequence>
<CustomAction
Id='RestartService'
Directory='TARGETDIR'
ExeCommand='[SystemFolder]cmd.exe net stop AppServerSvc && net start AppServerSvc'
Return='asyncWait'
Execute='deferred'
/>
If you schedule the upgrade MSI during the transaction, for example use:
MajorUpgrade/#Schedule='afterInstallInitialize' or
MajorUpgrade/#Schedule='afterInstallExecute' or
MajorUpgrade/#Schedule='afterInstallExecuteAgain'
and use the ServiceControl element to start/stop/restart the service then the Windows Installer will do all the work for you.
This is by far the most recommended way to accomplish your goal.
I have an c# application that I am installing during cleanboot on a windows mobile 6.1 device. It installs correctly, however, I need to get it to autostart after cleanboot.
I always have to warmboot the handheld after cleanboot to make it start.
How can I avoid this?
I asume, you are using a CAB file to install your C# app during cleanboot.
You may use a setup.dll inside the cab to start your app after the cab files have been installed using the DLL's Install_Exit function call (setupdll sample for example here: http://www.codeproject.com/Articles/7724/Creating-Pocket-PC-Application-Setup-Packages-Usin). But MS states you cannot rely on calling files of the cab install itself.
Another approach would be a seond cab that is installed after your C# app install and just calls your app, even using a setup dll.
See also http://msdn.microsoft.com/en-us/library/bb158796.aspx for howto pack several cabs into one install.
The problem with cleanboot installers and AutoStart is, that the OS already has run \Windows\StartUp and also other autostarts when the cab has been installed. Therefor you normally need a reboot that then executes your app using StartUp (or HKLM\Init).
You may also use a scripting engine to install the cab and then launch your installed app. For example use MortScript, which supports being used as "AutoStart.exe" inside SD Card\2577 or similar dir (Volume name\2577). The the script can call wceload.exe to install your app and afterwards start the executable of the installed app. Something like using a batch.
As this is an Intermec install, you can use \Flash File Store\UserAutoInstall_sstransferagent.xml to automate the install and launch of the app.
For example: Your cab is at \Flash File Store\MyInstall\MyCab.cab and installs MyApp.exe to \Program Files\MyApp:
<?xml version="1.0"?>
<Devices>
<Device Type="" Family="" Model="" Boot="">
<Files SrcDir="\Flash File Store\UserAutoInstall">
<File SrcName=""
DestName="wceload.exe"
DestDir="\Windows"
Run="true"
CmdLine='"\Flash File Store\MyInstall\MyCab.cab" /silent /verifyconfig /nodelete'
/>
<File SrcName=""
DestName="MyApp.exe"
DestDir="\Program Files\MyApp\MyApp.exe"
Run="NoWait"
CmdLine=''
/>
</Files>
</Device>
</Devices>
regards