oleg-shilo / wixsharp

Framework for building a complete MSI or WiX source code by using script files written with C# syntax.
MIT License
1.1k stars 174 forks source link

appesearch.getproductversionfromupgradecode #532

Closed Torchok19081986 closed 5 years ago

Torchok19081986 commented 5 years ago

Hallo Oleg, i have one bigger problem. i tried to get version from msi by upgradecode like in example of beforeinstall, but appsearch.getproductversionfromupgradecode(e.upgradecode) return null if product isnt installed. It appears NullrefException. in Wix# Version until 1.9.2 works. Tested with 1.8.2 and with 1.6.5 and 1.4.2. Here works. What i tried to do ist, if msi doenst found softwareversion by upgrade it cancel update to newer version, here should customer uninstall current version and installed it from fullversion with right one project.guid, only then can update be executed. it worked in previously version of wix#. after some view more tests, i can say nearly to 100% it crashed in step Appsearch by upgradecode in Version of wix# 1.9.2.

some strage behaviour : if set it in event beforeinstall like var detectversion = AppSearch.GetProductVersionFromUpgradeCode(e.UpgradeCode) <-- here crashed.

Torchok19081986 commented 5 years ago

After some investigate in Registry i found out, that behavior comes from plattfrom and installer. if i set to x64 and in fullinstaller and installed it, works great. update to newer version by same GUID works, but it installed / updated registry in in x86 under/microsoft/windows/currentversion/uninstall/{productcode}. here runs appsearch.getprodructversuinfromupgradecode or isproductinstalled by productode to NullRegException, otherwise if i set Plattform to x86 i installed update on 64-bit PC in x86 Path to Registry. How do i set Appsearch to x64 or x86 Registry ?

Torchok19081986 commented 5 years ago

Hi Oleg, after i do some research and testing on VM, i found out, that i only need to cancel installation at some point, but e.Manageui.shell.errordetected = true and customdescription not be executed and msi install always msi for upgrade as new product. I tried also with e.result = actionresult.failure, but this brought not improvement. And in Log is INSTALL Action return value 3 and 1603 error on msi. It looks like before_install always be executed 2 times. first at install and second at upgrading. This behaviour i cant cancel. Can you pls help me with ? What should i do, to cancel installation and provide custom description.

oleg-shilo commented 5 years ago

It looks like before_install always be executed 2 times. first at install and second at upgrading.

Correct. From MSI point of view the custom action that fires that before_install event is scheduled as "before install":

<Custom Action="WixSharp_BeforeInstall_Action" Before="InstallFiles">1</Custom>

If you want to distinguish install and upgrade you will need to analyze the event args:

static void project_AfterInstall(SetupEventArgs e)
{

    if (!e.IsUpgrading)
    {
    }
    else if (!e.IsInstalling)
    {
    }
Torchok19081986 commented 5 years ago

Ok. thanks for info. Current my qc for before_install looks like : var detectversion = appsearch.isproductinstalled(e.productcode); if(detectedversion == false) { e.managedui.shell.errordetected = true; e.managedui.shell.Customerrordescription = "setup was aborted, ..."; e.result = actionresult.failure; } but here in if-condition return false, msi doesnt cancel installation. I tried it also as local admin restart as admin elevated, no improvement. I always thought, that errodetected = true and e.result = actionresult.failure cancel msi installaion, but for me msi doesnt cancel installation anyway. This behaviour is always same in each new project of wix# and customUI.

oleg-shilo commented 5 years ago

Can you please use code formatting. It's very difficult to read your posts. Please enclose the code fragments in the proper mark-down decoration:

```C# your code goes here ```


errodetected = true

No, it is only used to indicate to the exit dialog that the setup failed message should be displayed on the dialog background.

e.result = actionresult.failure

No, it does indicate to the MSI runtime that this custom action failed. That's it. It is entirely up to MSI to decide if the upgrade should be aborted or not. Apparently it decides that it should not. Regrettable, but nothing we can do about it.

I think what you are trying to do is really pushing MSI and it just cannot fully cope with your requirements. There is a chance that you may find some exotic solution to you problem but the best approach would be to actually rethink your deployment strategy. This is how I feel about it.

Torchok19081986 commented 5 years ago
var detectversion = appsearch.isproductinstalled(e.productcode);
if(detectedversion == false) { e.managedui.shell.errordetected = true; e.managedui.shell.Customerrordescription = "setup was aborted, ..."; e.result = actionresult.failure; }

if i do so like in my description, i got always setup was aborted because of error detected ... your system was not modifying. Start installer later, something like that. i want only to check if my product are installed or not, and if not, upgrade or update to newer version should be stopped thats all. if i try

appsearch.getproductversionfromupgradecode(e.upgradecode) 

in log are exception of Reflection: System.TargetInovacationException and INSTALL Action are return value 3.

oleg-shilo commented 5 years ago

...but for me msi doesnt cancel installation anyway.

... i got always setup was aborted because of error detected

Your two statements above contradict each other.

May be it is the language. Are you using any translation services? If you do the may be inadequate translation creates the confusion...

Torchok19081986 commented 5 years ago

Ok. i describe different. msi exitdialog in desc.text error comes not from customdescription. I think this comes from standard msi error "setup was aborted.... Your system was not modifying...". message and if i open log in exitdialog, there is targetinovacationexception --> nullreferenceexception.

e.ManagedUI.Shell.Errordetected = true;
e.managedui.shell.Customerrordescription = "setup was aborted, ...";
e.Result = ActionResult.Failure;

if i set customdescription in before_install setupevent , message not appear on exitdialog in description textbox, instead of exitdialog displays stardard error. It comes form localisation.wxl file . In String Id="FatalErrorDescription1" Overridable="yes" Der Setup-Assistent für [ProductName] wurde aufgrund eines Fehlers vorzeitig beendet. Das System wurde nicht verändert. Sie müssen den Setup-Assistenten erneut ausführen, um dieses Programm zu einem späteren Zeitpunkt zu installieren. it says : "The Setup Wizard for [ProductName] ended prematurely due to an error. The system has not changed. You will need to run the setup wizard again to install this program later."

It translate to german, but it says error what i see in exitdialog on [FatalErrorDescription1]. exitdialog doesnt write my customdescription in [ExitdialogDescription].

Torchok19081986 commented 5 years ago

my Installlog after installation with error looks like : Info: === Logging started: 16.11.2018 10:24:18 === CommonData: Message type: 0, Argument: 1033 CommonData: Message type: 1, Argument: MyProduct ActionStart: Action 10:24:18: INSTALL. Info: Action start 10:24:18: INSTALL. CommonData: 1: 0 2: 1033 3: 1252 CommonData: 1: 0 2: 1033 3: 1252 Info: === Logging started: 16.11.2018 10:24:18 === CommonData: Message type: 0, Argument: 1033 CommonData: Message type: 1, Argument: MyProduct ActionStart: Action 10:24:18: INSTALL. Info: Action start 10:24:18: INSTALL. InstallStart: 1: MyProduct 2: {B3FEAB84-8F9A-4A60-898A-8D2C1FA87803} ActionStart: Action 10:24:18: FindRelatedProducts. Searching for related applications Info: Action start 10:24:18: FindRelatedProducts. Info: Action ended 10:24:18: FindRelatedProducts. Return value 1. ActionStart: Action 10:24:18: WixSharp_InitRuntime_Action. Info: Action start 10:24:18: WixSharp_InitRuntime_Action. Info: SFXCA: Extracting custom action to temporary directory: C:\WINDOWS\Installer\MSI6E62.tmp-\ Info: SFXCA: Binding to CLR version v2.0.50727 Info: Calling custom action WixSharp!WixSharp.ManagedProjectActions.WixSharp_InitRuntime_Action Info: Action ended 10:24:18: WixSharp_InitRuntime_Action. Return value 1. ActionStart: Action 10:24:18: AppSearch. Searching for installed applications Info: Action start 10:24:18: AppSearch. Info: Action ended 10:24:18: AppSearch. Return value 0. ActionStart: Action 10:24:18: ValidateProductID. Info: Action start 10:24:18: ValidateProductID. Info: Action ended 10:24:18: ValidateProductID. Return value 1. ActionStart: Action 10:24:18: CostInitialize. Computing space requirements Info: Action start 10:24:18: CostInitialize. Info: Action ended 10:24:18: CostInitialize. Return value 1. ActionStart: Action 10:24:18: FileCost. Computing space requirements Info: Action start 10:24:18: FileCost. Info: Action ended 10:24:18: FileCost. Return value 1. ActionStart: Action 10:24:18: CostFinalize. Computing space requirements Info: Action start 10:24:18: CostFinalize. Info: Action ended 10:24:18: CostFinalize. Return value 1. ActionStart: Action 10:24:18: InstallValidate. Validating install Info: Action start 10:24:18: InstallValidate. Info: Action ended 10:24:18: InstallValidate. Return value 1. ActionStart: Action 10:24:18: InstallInitialize. Info: Action start 10:24:18: InstallInitialize. Info: Action ended 10:24:18: InstallInitialize. Return value 1. ActionStart: Action 10:24:18: RemoveExistingProducts. Removing applications Info: Action start 10:24:18: RemoveExistingProducts. Info: Action ended 10:24:18: RemoveExistingProducts. Return value 1. ActionStart: Action 10:24:18: ProcessComponents. Updating component registration Info: Action start 10:24:18: ProcessComponents. ActionStart: Action 10:24:18: GenerateScript. Generating script operations for action: ActionData: Updating component registration Info: Action ended 10:24:18: ProcessComponents. Return value 1. ActionStart: Action 10:24:18: UnpublishFeatures. Unpublishing Product Features Info: Action start 10:24:18: UnpublishFeatures. Info: Action ended 10:24:18: UnpublishFeatures. Return value 1. ActionStart: Action 10:24:18: RemoveFiles. Removing files Info: Action start 10:24:18: RemoveFiles. Info: Action ended 10:24:18: RemoveFiles. Return value 0. ActionStart: Action 10:24:18: WixSharp_BeforeInstall_Action. Info: Action start 10:24:18: WixSharp_BeforeInstall_Action. Info: SFXCA: Extracting custom action to temporary directory: C:\WINDOWS\Installer\MSI7058.tmp-\ Info: SFXCA: Binding to CLR version v2.0.50727 Info: Calling custom action WixSharp!WixSharp.ManagedProjectActions.WixSharp_BeforeInstall_Action Info: WixSharp aborted the session because of the error: System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.NullReferenceException: bei WixSharp_Setup2.Program.Project_BeforeInstall(SetupEventArgs e) --- Ende der internen Ausnahmestapelüberwachung --- bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean skipVisibilityChecks) bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture) bei WixSharp.ManagedProject.InvokeClientHandler(String info, SetupEventArgs eventArgs) bei WixSharp.ManagedProject.InvokeClientHandlers(Session session, String eventName, IShellView UIShell) Info: CustomAction WixSharp_BeforeInstall_Action returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) Info: Action ended 10:24:21: WixSharp_BeforeInstall_Action. Return value 3. CommonData: Message type: 2, Argument: 0 CommonData: Message type: 2, Argument: 1 Info: Action ended 10:24:21: INSTALL. Return value 3. InstallEnd: 1: MyProduct 2: {B3FEAB84-8F9A-4A60-898A-8D2C1FA87803} 3: 3 CommonData: 1: 2 2: 0 CommonData: 1: 2 2: 1 Info: Action ended 10:24:21: INSTALL. Return value 3.

oleg-shilo commented 5 years ago

OK, judging from you log your routine throws an exception at runtime. It happens before you assign the error message that's why the your error message does not appear in the ExitDialog.

This is how the exceptions in the client code are handled:

internal static ActionResult InvokeClientHandlers(Session session, string eventName, IShellView UIShell = null)
{
    var eventArgs = Convert(session);
    eventArgs.ManagedUI = UIShell;

    try
    {
        string handlersInfo = session.Property("WixSharp_{0}_Handlers".FormatWith(eventName));

        if (!string.IsNullOrEmpty(handlersInfo))
        {
            foreach (string item in handlersInfo.Trim().Split('\n'))
            {
                InvokeClientHandler(item.Trim(), eventArgs);
                if (eventArgs.Result == ActionResult.Failure || eventArgs.Result == ActionResult.UserExit)
                    break;
            }

            eventArgs.SaveData();
        }
    }
    catch (Exception e)
    {
        session.Log("WixSharp aborted the session because of the error:" + Environment.NewLine + e.ToPublicString());
        if (session.AbortOnError())
            eventArgs.Result = ActionResult.Failure;
    }
    return eventArgs.Result;
}

You will need to debug your routine or use any other troubleshooting technique. But basically your code is not executed because of the runtime exception that you will need to eliminate.

Torchok19081986 commented 5 years ago

Thanks for info. Ok, i going try to search for my problem in beforeinstall.

if(e.Installing)
{
 var installed = Appsearch.IsProductinstalled(e.Productcode);
    if(installed == false)
   {
      e.ManageUI.Shell.Errordetected = true;
      e.ManageUI.Shell.CustomDescription = "Info why setup was aborted....";
      e.Result = ActionResult.Failure;

   }
}

in Line e.ManageUI.Shell.Errordetected = true, i got Problem. If i do set Appsearch.GetVersionFromUpgradeCode(e.Upgradecode) appears same Error in Dialog.

It looks like, some files are missing on targetsystem, may be some dlls or in GAC installed Dlls ? WixToolset are in 3.11 installed , this VM was completly newcreated. VS Version 15.9, NET Framenwork 4.7.1, Windows Version 1809, Target .NET Framework is 4.5, but change .NET Framework to any another version brought no improvment. I tested 4.5 up to 4.7.1 for all .NET Framework. After research and some tries i can with 100% say, targetsystem doesnt recognize wixsharp.dll in installation. Tested with Wixsharp 1.9.2 and 1.6.5.1 both version have a same errors on same line. Which .NET Framework you used to create current Wixsharp.dll ?

if you want to reproduce error: create new ManagedProject with CustomUI. set standardinfo for installer like version, installerversion etc. Important: create evetnts like afterisnstall, beforeinstall. Set code like my code from above. Build msi and try to install it. Error appears in Before_Install - CA. Can do nothing about it. Only execlude before_install helps.