Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Type 2 CA: Run an EXE


8 replies to this topic

Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 04 May 2011 - 15:57

Folks,

I have a very small EXE which I want to run early in the Installer (immediate, before any UI). Think of it as a kind of lauch condition, but by different means.

The EXE simply tries to instantiate a SharePoint Farm object, in order to confirm that the current user has the necessary rights to the SharePoint Server "Farm". If he does not, the object will not be instantiated, and the EXE will return a non-zero ERRORLEVEL.

Using ORCA, I put the EXE in the Binary table; I added a Type 2 CA with a reference to the EXE, and added the CA to the InstallUISequence right after LaunchConditions. I added an entry in the Error Table for the ERRORLEVEL (25000) and text for the message which says "you don't have necessary rights, blah blah."

Well, this test always succeeds, even when it shouldn't. The log always says the EXE returned a "1" (log excerpt below).

My questions:

1. How should the EXE communicate its result to MSI? ERRORLEVEL seems not to be working.
2. Why is MSI not treating the non-zero return a "success"? I want it to be seen as a "failure", to trigger an error message, and to quit the install.

What am I doing wrong?

Thanks,
ScottM



MSI © (B4:00) [10:51:10:633]: Doing action: Check_Farm_Access
Action 10:51:10: Check_Farm_Access.
Action start 10:51:10: Check_Farm_Access.
MSI © (B4:00) [10:51:10:633]: Note: 1: 2235 2: 3: ExtendedType 4: SELECT `Action`,`Type`,`Source`,`Target`, NULL, `ExtendedType` FROM `CustomAction` WHERE `Action` = 'Check_Farm_Access'
Action ended 10:51:12: Check_Farm_Access. Return value 1.

T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com

Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 04 May 2011 - 17:35

Folks,

UPDATE: The EXE run the by Custom Action was tweaked, and now correctly emits an error 25000 when it decides the install should no longer continue. However, instead of issuing the message associated with 25000 in the Error table, it just pops up a box which says:

"There is a problem with this Windows Installer package. A Program run as part of the setup did not finish as expected. Contact your support personnel or package vendor."

Click OK on this box and the installer quits. It never displays the error message I set up for that error code (25000) in the Error Table.

So, when running an EXE in a CA to check on prerequisite conditions, how does one communicate the result to the MSI, and from there, issue a meaningful message to the user?

Excerpt from the log follows.


Thanks,
ScottM

MSI © (E4:4C) [11:22:36:237]: Doing action: Check_Farm_Access
Action 11:22:36: Check_Farm_Access.
Action start 11:22:36: Check_Farm_Access.
MSI © (E4:4C) [11:22:36:237]: Note: 1: 2235 2: 3: ExtendedType 4: SELECT `Action`,`Type`,`Source`,`Target`, NULL, `ExtendedType` FROM `CustomAction` WHERE `Action` = 'Check_Farm_Access'
CustomAction Check_Farm_Access returned actual error code 25000 (note this may not be 100% accurate if translation happened inside sandbox)
MSI © (E4:4C) [11:22:37:346]: Note: 1: 1722 2: Check_Farm_Access 3: C:\Users\smayham\AppData\Local\Temp\3\MSI54CE.tmp 4:
Info 2898.For VSI_MS_Sans_Serif13.0_0_0 textstyle, the system created a 'MS Sans Serif' font, in 0 character set, of 13 pixels height.
DEBUG: Error 2835: The control ErrorIcon was not found on dialog ErrorDialog
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2835. The arguments are: ErrorIcon, ErrorDialog,
Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action Check_Farm_Access, location: C:\Users\smayham\AppData\Local\Temp\3\MSI54CE.tmp, command:
MSI © (E4:4C) [12:30:53:769]: Product: Infor10 Workspace-SyteLine Plug-in -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action Check_Farm_Access, location: C:\Users\smayham\AppData\Local\Temp\3\MSI54CE.tmp, command:

Action ended 12:30:53: Check_Farm_Access. Return value 3.


T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com

Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 04 May 2011 - 19:03

ANOTHER UPDATE: I see now that the EXE must not emit a return value other than zero, if I want to maintain control over what's going on. So, it appears that the EXE must communicate with the installer by setting a Condition.

How does an EXE do that?

Thanks,
ScottM
T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 05 May 2011 - 10:42

You are right: anything other than 0 will be interpretedf as the custom action failing, and will immediately abort the install.
Unfortunately an EXE can't set a property in the installer, only a DLL or a script custom action can. So either create a DLL to do the work that your EEXE does, or create a DLL or VBScript or JavaScript to wrap your EXE, get the exit code, store it in a property and then condition your error custom action (type 19) based on that property.

Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 05 May 2011 - 13:37

Stefan,

That brings me around full circle - I started with a VBScript CA. However, the DLL which is ultimately at the center of this effort (SharePoint.dll) does not have COM wrappers implemented for any of its objects or methods, so VbScript cannot access it directly. That's what prompted the move to an EXE.

A major constraint on this particular effort is the fact that what I'm trying to do is something like a LaunchCondition, so the CA is immediate and directly follows the LaunchCondition action in the InstallUISequence. As such, it cannot use any files in the installer's "payload", but rather must use a script/DLL/EXE streamed in the Binary Table.

How would a DLL, such as you describe, set a Property? I assume there is an MSI API call for this? Do you know of some sample code (C++, C#, whatever) which does this?

Thanks,
ScottM
T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 05 May 2011 - 14:36

In a DLL you can call MsiSetProperty() and you can store the DLL in the Binary table.

Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 05 May 2011 - 20:54

Stefan,

I'm sorry to keep hammering on the same subject. I just spent several hours with a C# guru trying to do this to no avail. Several non-negotiables:

1. The DLL must be x64 because what it is testing is a SharePoint object.
2. The DLL must be .NET because that is the world in which SharePoint lives.
3. This implies C#.

I've been scouring the web, and found this one interesting item:

[DllImport("msi.dll", CharSet=CharSet.Unicode)]
static extern int MsiSetProperty(IntPtr hInstall, string szName, string szValue);

Assuming I understand the MSI interface correctly, the Installer calls the dll, with one parameter, which is the handle (hInstall). The code above looks so simple as to be hard to believe.

Can anyone confirm that this is valid?

One other thing regarding MSI.dll - on 64-bit systems (like my Windows 7), there are 4 of them, one of which is larger than the others. Am I safe in assuming the the above DllImport statement would get the correct one?

Thanks,
ScottM
T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com

akerl

akerl
  • Full Members
  • 104 posts

Posted 06 May 2011 - 12:33

Scott,
MSI can't use .NET assemblies as .dll custom action, directly. The only way to do this, is by using DTF. DTF is part of WIX (http://wix.sourceforge.net/) and has a wrapper for managed CA's

Andreas

Andreas Kerl

Inside Windows Installer 4.5
ISBN 3-86645-431-7


Scott Mayham

Scott Mayham
  • Full Members
  • 54 posts

Posted 06 May 2011 - 17:53

Andreas,

That's what I thought as well, and it may yet prove to be true. I'm determined to find out.

A co-worker pointed out that Microsoft addressed this seemingly insoluble problem by providing "InterOp" facilities to .NET languages. These facilities do more than I will discuss here, but the thing that I care about is the ability to "decorate" (Microsoft's term) my interfaces so that my dll's methods can be called by MSI, by making them appear as Win32 Com interfaces, which is what MSI expects. Moreover, when I call MSI back to set a Property (MsiSetProperty), that interface is similarly decorated. Thus, my little .NET DLL is able to call and be called by software which only knows the Win32/COM interface. Sounds neat, and I'm working on coding my DLL today. This thread will soon reveal how successful I am.

BTW, anyone who knows of a content-rich (which eliminates MSDN) website, blog, or forum where Interop is discussed, please feel free to provide a link.

Regards,
ScottM
T. Scott Mayham
Senior Software Engineer - Innovations
678 319 8384
Scott.Mayham@Infor.com