Wixsharp: Issue with executing ManagedAction before StartServices

Created on 3 Sep 2018  ·  5Comments  ·  Source: oleg-shilo/wixsharp

Hello Oleg!
(Sorry for my English)
I created a text installation package and then I ran it through a test application but could not defeat the problem.
In the process of performing such actions as copying new files, installing new services, starting services are repeated twice. However, this is not reflected in the Log file.
After the first execution of these actions, files are not copied, the service is not installed and of course could not be started, but second execution fixes that issue.
The main problem is that CustomAction with the parameters (When.Before, Step.InstallServices) or (When.After, Step.InstallFiles) is not performed after the first Actions and performed only after second execution.
I added a delay in execution (2 seconds) and was able to match the Actions in the MSI LOG file and the generated GenericSetup.ActionStarted event. It turned out that the second set of Actions (Copying new files, Installing new services, Starting services) is performed between these 2 lines of the LOG file.
Action start 18:23:16: InstallFinalize.
Action ended 18:23:35: InstallFinalize. Return value 1.
It was expected that in CustomAction the configuration file will change before the service starts. But I cannot do this in the case of first time execution, because neither the folder nor the files yet exist. And I cannot add CustomAction after second execution (only if I execute after InstallFinalize), since the file is not configured, so the service will not start and installation will be rolled back.
How can i add CustomAction after step: 06:55:30.5546 - Starting services (in GenericSetup.ActionStarted Event)?

Thanks in advance for waste your time.

Russian version
Олег, добрый день!
Прощу прощения, за беспокойство, но не могу понять в чем дело.
Я создаюл текстовый инсталяционный пакет, а затем запускаю его через тестовое приложение и не могу победить следующую проблему.
В процессе выполнения Actions: Copying new files, Installing new services, Starting services вполняются 2 раза подряд. При этом в Log файле это не отражается.
При первыом выполнеии этих Action'ов файлы фактически не копируются и сервис не устанавливается и не запускается, а происходит это только во второй раз. То есть, после 1 раза, папка с файлами и сервис не создаются.
Сама проблема в том, что CustomAction с параметрами When.Before, Step.InstallServices или Step.InstallFiles выполняется после первых Action'ов, а не последних.
После того как я добавил задержку в выполнении (2 секунды) я смог сопоставить Action'ы в LOG файле MSI и возбуждаемым событием GenericSetup.ActionStarted. Оказалось, что второй набор Action'ов (Copying new files, Installing new services, Starting services) выполняется между вот этими 2 строками LOG файла.
Action start 18:23:16: InstallFinalize.
Action ended 18:23:35: InstallFinalize. Return value 1.
Смысл был в том, что в Action изменить конфигурационный файл до запуска сервиса, но сделать я этого не могу, как как при выполнении 1 прохода, ни папки, ни файлов еще не существует. А добавить CustomAction после 2 прохода я тупо не могу, только если выполнять после InstallFinalize, но так как файл не сконфигурирован, сервис не запустится и произойдет Rollback установки.

Project code

```c#
static void Main(string[] args)
{
string projectName = "Test application";
Version ver = new Version("1.4.0.5");
Guid guid = GenerateSeededGuid(projectName, ver);
Guid updateCode = new Guid("01d89112-f63e-47e9-ba0f-a297cf632020");

        var project = new Project("Test application",
            new Dir(@"[INSTALLDIR]",
                new File(@"..\WpfApp1\bin\Debug\WpfApp1.exe"),
                new File(@"..\WpfApp1\bin\Debug\WpfApp1.pdb"),
                new File(@"..\MyService\bin\Debug\MyService.exe")
                {
                    ServiceInstaller = new ServiceInstaller()
                    {
                        Name = "TEST_SERVICE",
                        DisplayName = "Test application service",
                        StopOn = SvcEvent.InstallUninstall_Wait,
                        RemoveOn = SvcEvent.Uninstall_Wait,
                        Account = "LocalSystem",
                        StartType = SvcStartType.auto,
                    }
                })
            )

        {
            Platform = Platform.x86,
            InstallScope = InstallScope.perMachine,
            ProductId = guid,
            GUID = guid,
            UpgradeCode = updateCode,
            EmitConsistentPackageId = true,
            Version = ver,
            UI = WUI.WixUI_Minimal,
            OutFileName = "WpfApp1.Install",
            MajorUpgrade = new MajorUpgrade
            {
                AllowSameVersionUpgrades = true,
                IgnoreRemoveFailure = false,
                AllowDowngrades = false,
                DowngradeErrorMessage = "A later version of [ProductName] is already installed. Setup will now exit.",
            },
            ControlPanelInfo =
            {
                Manufacturer = "Horns and hooves Inc",
                ProductIcon = "HAH_LOGO.ico"
            },
            Properties = new Property[] 
            {
            },
            DefaultRefAssemblies = new List<string>(1)
            {
                @"bin\Debug\WixSharp.UI.dll",
            },
            Actions = new [] 
            {
                new ManagedAction(CustumActions.ConfigurationAction, Return.check, When.Before, Step.StartServices, Condition.NOT_Installed),
            }


        };

        project.BuildMsi();

    }
</details>
<details><summary>GenericSetup.ActionStarted Event</summary>

Product name: Test application
CanInstall: True
CanUnInstall: False
CanRepair: False
ProductVersion: 1.4.0.5
ErrorStatus:
MsiErrorCode: 0

Press [I] for install, [U] for unintsall, [ESC] for exit:[Install]

06:54:33.7103 - Searching for related applications
06:54:35.7241 - Evaluating launch conditions
06:54:37.7334 - Computing space requirements
06:54:39.7451 - Computing space requirements
06:54:41.7490 - Computing space requirements
06:54:43.7639 - Migrating feature states from related applications
06:54:45.7668 - Validating install
06:54:47.8011 - Removing applications
06:54:49.8203 - Updating component registration
06:54:51.8505 - Generating script operations for action:
06:54:53.8568 - Unpublishing Product Features
06:54:55.8638 - Stopping services
06:54:57.8733 - Deleting services
06:54:59.8805 - Removing files
06:55:01.8846 - Copying new files
06:55:03.8985 - Installing new services
CustromAction Execute (MessageBox)
06:55:11.4637 - Starting services
06:55:13.4708 - Registering user
06:55:15.4757 - Registering product
06:55:17.4834 - Publishing Product Features
06:55:19.4904 - Publishing product information
06:55:21.5237 - Updating component registration
06:55:23.5331 - Stopping services
06:55:26.5407 - Copying new files
06:55:28.5504 - Installing new services
06:55:30.5546 - Starting services
06:55:32.6197 - Registering product
06:55:34.6543 - Publishing Product Features
06:55:36.6614 - Publishing product information
06:55:38.7075 - Removing backup files
COMPLETE

</details>

<details><summary>MSI Log File</summary>

Action start 18:54:33: INSTALL.

Action start 18:54:35: FindRelatedProducts.
Action ended 18:54:35: FindRelatedProducts. Return value 1.
Action start 18:54:37: LaunchConditions.
Action ended 18:54:37: LaunchConditions. Return value 1.
Action start 18:54:37: ValidateProductID.
Action ended 18:54:37: ValidateProductID. Return value 1.
Action start 18:54:39: CostInitialize.
Action ended 18:54:39: CostInitialize. Return value 1.
Action start 18:54:41: FileCost.
Action ended 18:54:41: FileCost. Return value 1.
Action start 18:54:43: CostFinalize.
Action ended 18:54:43: CostFinalize. Return value 1.
Action start 18:54:45: MigrateFeatureStates.
Action ended 18:54:45: MigrateFeatureStates. Return value 0.
Action start 18:54:47: InstallValidate.
Action ended 18:54:47: InstallValidate. Return value 1.
Action start 18:54:49: RemoveExistingProducts.
Action ended 18:54:49: RemoveExistingProducts. Return value 1.
Action start 18:54:49: InstallInitialize.
Action ended 18:54:49: InstallInitialize. Return value 1.
Action start 18:54:51: ProcessComponents.
Action ended 18:54:53: ProcessComponents. Return value 1.
Action start 18:54:55: UnpublishFeatures.
Action ended 18:54:55: UnpublishFeatures. Return value 1.
Action start 18:54:57: StopServices.
Action ended 18:54:57: StopServices. Return value 1.
Action start 18:54:59: DeleteServices.
Action ended 18:54:59: DeleteServices. Return value 1.
Action start 18:55:01: RemoveFiles.
Action ended 18:55:01: RemoveFiles. Return value 0.
Action start 18:55:03: InstallFiles.
Action ended 18:55:03: InstallFiles. Return value 1.
Action start 18:55:05: InstallServices.
Action ended 18:55:05: InstallServices. Return value 1.
Action start 18:55:05: ConfigurationAction.
SFXCA: Extracting custom action to temporary directory: C:\WINDOWS\Installer\MSID3A9.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action InstallerApp!InstallerApp.CustumActions.ConfigurationAction
Action ended 18:55:11: ConfigurationAction. Return value 1.
Action start 18:55:13: StartServices.
Action ended 18:55:13: StartServices. Return value 1.
Action start 18:55:15: RegisterUser.
Action ended 18:55:15: RegisterUser. Return value 1.
Action start 18:55:17: RegisterProduct.
Action ended 18:55:17: RegisterProduct. Return value 1.
Action start 18:55:19: PublishFeatures.
Action ended 18:55:19: PublishFeatures. Return value 1.
Action start 18:55:21: PublishProduct.
Action ended 18:55:21: PublishProduct. Return value 1.
Action start 18:55:21: InstallFinalize.
=> Вся движуха с копированием файлов и установкой сервиса происходит в этот момент, а не выше
Action ended 18:55:40: InstallFinalize. Return value 1.
Action ended 18:55:40: INSTALL. Return value 1.
Property(S): UpgradeCode = {01D89112-F63E-47E9-BA0F-A297CF632020}
Property(S): INSTALLDIR = Z:\TESTAPP\
Property(S): WixUIRMOption = UseRM
Property(S): ALLUSERS = 1
Property(S): ARPNOMODIFY = 1
Property(S): TARGETDIR = D:\
Property(S): SourceDir = C:\Users\roman.meytes\source\repos\wix_invest\ConsoleApp1\ConsoleApp1\
Property(S): VersionNT = 603
Property(S): ARPPRODUCTICON = app_icon.ico
Property(S): Manufacturer = Horns and hooves Inc
Property(S): ProductCode = {BD5EB1C1-34EF-0F73-FE89-E83AD16A885A}
Property(S): ProductLanguage = 1033
Property(S): ProductName = Test application
Property(S): ProductVersion = 1.4.0.5
Property(S): DefaultUIFont = WixUI_Font_Normal
Property(S): WixUI_Mode = Minimal
Property(S): ErrorDialog = ErrorDlg
Property(S): SecureCustomProperties = WIX_DOWNGRADE_DETECTED;WIX_UPGRADE_DETECTED
Property(S): MsiLogFileLocation = C:\Users\roman.meytes\source\repos\wix_invest\ConsoleApp1\ConsoleApp1\WpfApp1.Install.msi.log
Property(S): ProductState = -1
Property(S): PackageCode = {BD5EB1C1-34EF-0F73-FE89-E83AD16A885A}
Property(S): PackagecodeChanging = 1
Property(S): CURRENTDIRECTORY = C:\Users\roman.meytes\source\repos\wix_invest\ConsoleApp1\InstallerExecutor\bin\Debug
Property(S): CLIENTUILEVEL = 3
Property(S): MSICLIENTUSESEXTERNALUI = 1
Property(S): CLIENTPROCESSID = 28976
Property(S): VersionDatabase = 200
Property(S): VersionMsi = 5.00
Property(S): VersionNT64 = 603
Property(S): WindowsBuild = 9600
Property(S): ServicePackLevel = 0
Property(S): ServicePackLevelMinor = 0
Property(S): MsiNTProductType = 1
Property(S): WindowsFolder = C:\WINDOWS\
Property(S): WindowsVolume = C:\
Property(S): System64Folder = C:\WINDOWS\system32\
Property(S): SystemFolder = C:\WINDOWS\SysWOW64\
Property(S): RemoteAdminTS = 1
Property(S): TempFolder = C:\Users\ROMAN~1.MEY\AppData\Local\Temp\
Property(S): ProgramFilesFolder = C:Program Files (x86)\
Property(S): CommonFilesFolder = C:Program Files (x86)\Common Files\
Property(S): ProgramFiles64Folder = C:Program Files\
Property(S): CommonFiles64Folder = C:Program Files\Common Files\
Property(S): AppDataFolder = C:\Users\roman.meytes\AppData\Roaming\
Property(S): FavoritesFolder = C:\Users\roman.meytes\Favorites\
Property(S): NetHoodFolder = C:\Users\roman.meytes\AppData\Roaming\Microsoft\Windows\Network Shortcuts\
Property(S): PersonalFolder = C:\Users\roman.meytes\Documents\
Property(S): PrintHoodFolder = C:\Users\roman.meytes\AppData\Roaming\Microsoft\WindowsPrinter Shortcuts\
Property(S): RecentFolder = C:\Users\roman.meytes\AppData\Roaming\Microsoft\Windows\Recent\
Property(S): SendToFolder = C:\Users\roman.meytes\AppData\Roaming\Microsoft\Windows\SendTo\
Property(S): TemplateFolder = C:ProgramData\Microsoft\Windows\Templates\
Property(S): CommonAppDataFolder = C:ProgramData\
Property(S): LocalAppDataFolder = C:\Users\roman.meytes\AppData\Local\
Property(S): MyPicturesFolder = C:\Users\roman.meytesPictures\
Property(S): AdminToolsFolder = C:ProgramData\Microsoft\Windows\Start MenuPrograms\Administrative Tools\
Property(S): StartupFolder = C:ProgramData\Microsoft\Windows\Start MenuPrograms\Startup\
Property(S): ProgramMenuFolder = C:ProgramData\Microsoft\Windows\Start MenuPrograms\
Property(S): StartMenuFolder = C:ProgramData\Microsoft\Windows\Start Menu\
Property(S): DesktopFolder = C:\UsersPublic\Desktop\
Property(S): FontsFolder = C:\WINDOWS\Fonts\
Property(S): GPTSupport = 1
Property(S): OLEAdvtSupport = 1
Property(S): ShellAdvtSupport = 1
Property(S): MsiAMD64 = 6
Property(S): Msix64 = 6
Property(S): Intel = 6
Property(S): PhysicalMemory = 16067
Property(S): VirtualMemory = 4208
Property(S): AdminUser = 1
Property(S): MsiTrueAdminUser = 1
Property(S): LogonUser = roman.meytes
Property(S): UserSID =
Property(S): UserLanguageID = 1033
Property(S): ComputerName = MEYTES-RA
Property(S): SystemLanguageID = 1049
Property(S): ScreenX = 1024
Property(S): ScreenY = 768
Property(S): CaptionHeight = 19
Property(S): BorderTop = 1
Property(S): BorderSide = 1
Property(S): TextHeight = 16
Property(S): TextInternalLeading = 3
Property(S): ColorBits = 32
Property(S): TTCSupport = 1
Property(S): Time = 18:55:40
Property(S): Date = 9/3/2018
Property(S): MsiNetAssemblySupport = 4.7.3056.0
Property(S): MsiWin32AssemblySupport = 6.3.17134.1
Property(S): RedirectedDllSupport = 2
Property(S): MsiRunningElevated = 1
Property(S): Privileged = 1
Property(S): USERNAME = Windows User
Property(S): DATABASE = C:\WINDOWS\Installer1a2fefe5.msi
Property(S): OriginalDatabase = C:\Users\roman.meytes\source\repos\wix_invest\ConsoleApp1\ConsoleApp1\WpfApp1.Install.msi
Property(S): UILevel = 2
Property(S): MsiUISourceResOnly = 1
Property(S): ACTION = INSTALL
Property(S): ROOTDRIVE = D:\
Property(S): CostingComplete = 1
Property(S): OutOfDiskSpace = 0
Property(S): OutOfNoRbDiskSpace = 0
Property(S): PrimaryVolumeSpaceAvailable = 0
Property(S): PrimaryVolumeSpaceRequired = 0
Property(S): PrimaryVolumeSpaceRemaining = 0
Property(S): INSTALLLEVEL = 1
Property(S): SOURCEDIR = C:\Users\roman.meytes\source\repos\wix_invest\ConsoleApp1\ConsoleApp1\
Property(S): SourcedirProduct = {BD5EB1C1-34EF-0F73-FE89-E83AD16A885A}
Property(S): ProductToBeRegistered = 1
=== Logging stopped: 9/3/2018 18:55:40 ===
MSI (s) (00:A8) [18:55:40:877]: Product: Test application -- Installation completed successfully.

MSI (s) (00:A8) [18:55:40:878]: Windows Installer installed the product. Product Name: Test application. Product Version: 1.4.0.5. Product Language: 1033. Manufacturer: Horns and hooves Inc. Installation success or error status: 0.
```

question

All 5 comments

Hi there.
I think in your case you would really benefit from switching to the _ManagedProject_. Have a look at Setup Events sample.
You can subscribe for the AfterInstall event and do the service management from there. You have warrantee that the all files are installed at that time. And the event handler also runs elevated.

Если быть кратким, то установка идет в 2 этапа.
На первом этапе идет генерация скриптов установки и отката, установщик пробегает по всем действиям, которые занесены в таблицу InstallExecuteSequence, и заносит все отложенные действия (deferred) в скрипты, все немедленные действия (immediate) он выполняет на этом этапе.
На втором этапе идет выполнение скрипта установки, все отложенные действия выполняются на этом этапе.
Из-за этих двух проходов кажется что все действия выполняются два раза, но реальные изменения идут только на втором этапе.
Если тебе нужно сделать подготовительные работы, без физического изменения системы, то твое действие может быть немедленным, указав Execute = immediate, а если хочешь изменить систему, то необходимо чтобы твое действие было отложенное указавExecute = deferred.


Надеюсь я по теме :)

Ты можешь просто поменять ManagedAction на ElevatedManagedAction, все его конструкторы выставляют Executeкак deferred.

@Xaddan , Спасибо огромное, всё супер!

@meytes Обращайся.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mgkeeley picture mgkeeley  ·  5Comments

ju2pom picture ju2pom  ·  5Comments

ayman-eltemsahi picture ayman-eltemsahi  ·  4Comments

ltemimi picture ltemimi  ·  5Comments

mattias-symphony picture mattias-symphony  ·  3Comments