-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Monty241 ease analysis missing method exception #1701
Monty241 ease analysis missing method exception #1701
Conversation
During analysis of a problem with a build, it occurred to me that when the first log destination fails, the virtual log (whatever that is) is neither fed with the log message. This behaviour hinders analysis. This patch improves logging capabilities, even when part of the log system is broken / generates an error. ``` {"itgenmsi151","Message":"** Info: === Logging started: 14-12-2024 14:32:14 ===" {"itgenmsi501","Message":"First chance exception handling of type 'InstallerException':" {"itgenmsi502","Message":"Exception of type 'Microsoft.Deployment.WindowsInstaller.InstallerException' was thrown. (type: InstallerException)" {"itgenmsj681","Message":"No exception data to register." {"itgenmsi504","Message":"Stack trace:" {"itgenmsi505","Message":" at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)" {"itgenmsi505","Message":" at System.Environment.get_StackTrace()" {"itgenmsi505","Message":" at Acme.Deploy.Error.CurrentDomain_FirstChanceException(Object sender, FirstChanceExceptionEventArgs e)" {"itgenmsi505","Message":" at Microsoft.Deployment.WindowsInstaller.Session.Message(InstallMessage messageType, Record record)" {"itgenmsi505","Message":" at Microsoft.Deployment.WindowsInstaller.Session.Log(String msg)" {"itgenmsi505","Message":" at WixSharp.MsiSessionAdapter.Log(String msg)" {"itgenmsi505","Message":" at Invantive.Deploy.Runtime.LogUtility.LogToSession(SessionState sessionState, String txt)" {"itgenmsi505","Message":" at Invantive.Deploy.Runtime.LogUtility.LogToSession(SessionState sessionState, TraceContext traceContext)" {"itgenmsi505","Message":" at Invantive.Deploy.Runtime.LogUtility.LogLine(SessionState sessionState, String txt, String messageCode)" {"itgenmsi505","Message":" at Invantive.Deploy.Runtime.LogUtility.LogLines(SessionState sessionState, String linePrefix, String[] lines, String messageCode)" {"itgenmsi505","Message":" at Invantive.Deploy.UI.ProgressDialog.ProcessMessage(InstallMessage messageType, Record messageRecord, MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton)" {"itgenmsi505","Message":" at WixSharp.UIShell.<>c__DisplayClass69_0.<ProcessMessage>b__1()" {"itgenmsi505","Message":" at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)" {"itgenmsi505","Message":" at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)" ```
The method `InvoiceClientHandlers` calls a method on basis of the value of the defined property `WixSharp_Load_Handlers`. Without this change, it is quite hard from the error log to pinpoint the cause when there are multiple handlers: ``` {"itgenmsi150","Message":"Start action indicated by user interface message from message record below - Load installation components." {"itgenmsj687","Message":"Line: Action 14:32:15: WixSharp_Load_Action. " {"itgenmsi151","Message":"** Info: Action start 14:32:15: WixSharp_Load_Action." {"itgenmsi151","Message":"** Info: SFXCA: Extracting custom action to temporary directory: C:\\Windows\\Installer\\MSI36D7.tmp-\\" {"itgenmsi151","Message":"** Info: SFXCA: Binding to CLR version v4.0.30319" {"itgenmsi151","Message":"** Info: Calling custom action WixSharp!WixSharp.ManagedProjectActions.WixSharp_Load_Action" {"itgenmsi151","Message":"** Info: WixSharp aborted the session because of the error:" {"itgenmsi151","Message":"** Info: System.MissingMethodException: Kan geen abstracte klasse maken." {"itgenmsi151","Message":"** Info: bij System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)" {"itgenmsi151","Message":"** Info: bij System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)" {"itgenmsi151","Message":"** Info: bij System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)" {"itgenmsi151","Message":"** Info: bij System.Activator.CreateInstance(Type type, Boolean nonPublic)" {"itgenmsi151","Message":"** Info: bij System.Activator.CreateInstance(Type type)" {"itgenmsi151","Message":"** Info: bij WixSharp.ManagedProject.InvokeClientHandlers(Session session, String eventName, IShellView UIShell)" {"itgenmsi151","Message":"** Info: CustomAction WixSharp_Load_Action returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)" {"itgenmsi151","Message":"** Info: Action ended 14:32:16: WixSharp_Load_Action. Return value 3." {"itgenmsi151","Message":"** Info: Action ended 14:32:16: INSTALL. Return value 3." {"itgenmsi154","Message":"End installation with message record below." {"itgenmsj685","Message":"Line: 1: Acme Program 24.0 2: {B117615F-ED98-4321-B110-94DA80017800} 3: 3 " {"itgenmsi152","Message":"** ** CommonData: 1: 2 2: 0 " {"itgenmsi152","Message":"** ** CommonData: 1: 2 2: 1 " {"itgenmsi151","Message":"** Info: Action ended 14:32:16: INSTALL. Return value 3." ``` With this change, the logging will be easier to interprete. Also, the exception is decorated with some background information to ease analysis when WixSharp logs these (our unhandled exception handler always prints these).
As a side note: this error on missing method exception occurred due to the use of:
in the C# code. This data is duplicated into the WXS and then dynamically called using reflection. Great mechanism. However, in combination with a A suggestion is to check on registration in the WXS that the methods must be public to formally allow calling from the outside. I am aware that reflection allows calling private members normally, but in this case DotBlur obfuscation renamed the method :-) Typically an error is registered like:
when the member's name is obfuscated. |
A great addition to the error handling. |
Unfortunately this would prevent using lambda expressions as event handlers since lambdas are wrapped in non-public classes In this case, WixSharp just follows the .NET lambda expression pattern for events - "invoke private type method" |
Yes, that is correct. Missed that one. Lambda expressions can be detected indirectly, but it is implementation dependant. Better to leave as you see as is. |
No description provided.