private static MethodInfo GetCustomActionMethod( Session session, string assemblyName, string className, string methodName) { Assembly customActionAssembly; Type customActionClass = null; Exception caughtEx = null; try { customActionAssembly = AppDomain.CurrentDomain.Load(assemblyName); customActionClass = customActionAssembly.GetType(className, true, true); } catch (IOException ex) { caughtEx = ex; } catch (BadImageFormatException ex) { caughtEx = ex; } catch (TypeLoadException ex) { caughtEx = ex; } catch (ReflectionTypeLoadException ex) { caughtEx = ex; } catch (SecurityException ex) { caughtEx = ex; } if (caughtEx != null) { session.Log("Error: could not load custom action class " + className + " from assembly: " + assemblyName); session.Log(caughtEx.ToString()); return(null); } MethodInfo[] methods = customActionClass.GetMethods( BindingFlags.Public | BindingFlags.Static); foreach (MethodInfo method in methods) { if (method.Name == methodName && CustomActionProxy.MethodHasCustomActionSignature(method)) { return(method); } } session.Log("Error: custom action method \"" + methodName + "\" is missing or has the wrong signature."); return(null); }
private static IEmbeddedUI InstantiateUI(Session session, string uiClass) { int assemblySplit = uiClass.IndexOf('!'); if (assemblySplit < 0) { session.Log("Error: invalid embedded UI assembly and class:" + uiClass); return(null); } string assemblyName = uiClass.Substring(0, assemblySplit); EmbeddedUIProxy.uiClass = uiClass.Substring(assemblySplit + 1); Assembly uiAssembly; try { uiAssembly = AppDomain.CurrentDomain.Load(assemblyName); // This calls out to CustomActionProxy.DebugBreakEnabled() directly instead // of calling EmbeddedUIProxy.DebugBreakEnabled() because we don't compose a // class.method name for this breakpoint. if (CustomActionProxy.DebugBreakEnabled(new string[] { "EmbeddedUI" })) { System.Diagnostics.Debugger.Launch(); } return((IEmbeddedUI)uiAssembly.CreateInstance(EmbeddedUIProxy.uiClass)); } catch (Exception ex) { session.Log("Error: could not load embedded UI class " + EmbeddedUIProxy.uiClass + " from assembly: " + assemblyName); session.Log(ex.ToString()); return(null); } }
private static bool DebugBreakEnabled(string method) { return(CustomActionProxy.DebugBreakEnabled(new string[] { method, EmbeddedUIProxy.uiClass + "." + method })); }
internal static int InvokeCustomAction(int sessionHandle, string entryPoint, IntPtr remotingDelegatePtr) { Session session = null; string assemblyName, className, methodName; MethodInfo method; try { MsiRemoteInvoke remotingDelegate = (MsiRemoteInvoke) Marshal.GetDelegateForFunctionPointer( remotingDelegatePtr, typeof(MsiRemoteInvoke)); RemotableNativeMethods.RemotingDelegate = remotingDelegate; sessionHandle = RemotableNativeMethods.MakeRemoteHandle(sessionHandle); session = new Session((IntPtr)sessionHandle, false); if (String.IsNullOrEmpty(entryPoint)) { throw new ArgumentNullException("entryPoint"); } if (!CustomActionProxy.FindEntryPoint( session, entryPoint, out assemblyName, out className, out methodName)) { return((int)ActionResult.Failure); } session.Log("Calling custom action {0}!{1}.{2}", assemblyName, className, methodName); method = CustomActionProxy.GetCustomActionMethod( session, assemblyName, className, methodName); if (method == null) { return((int)ActionResult.Failure); } } catch (Exception ex) { if (session != null) { try { session.Log("Exception while loading custom action:"); session.Log(ex.ToString()); } catch (Exception) { } } return((int)ActionResult.Failure); } try { // Set the current directory to the location of the extracted files. Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); object[] args = new object[] { session }; if (DebugBreakEnabled(new string[] { entryPoint, methodName })) { string message = String.Format( "To debug your custom action, attach to process ID {0} (0x{0:x}) and click OK; otherwise, click Cancel to fail the custom action.", System.Diagnostics.Process.GetCurrentProcess().Id ); MessageResult button = NativeMethods.MessageBox( IntPtr.Zero, message, "Custom Action Breakpoint", (int)MessageButtons.OKCancel | (int)MessageIcon.Asterisk | (int)(MessageBoxStyles.TopMost | MessageBoxStyles.ServiceNotification) ); if (MessageResult.Cancel == button) { return((int)ActionResult.UserExit); } } ActionResult result = (ActionResult)method.Invoke(null, args); session.Close(); return((int)result); } catch (InstallCanceledException) { return((int)ActionResult.UserExit); } catch (Exception ex) { session.Log("Exception thrown by custom action:"); session.Log(ex.ToString()); return((int)ActionResult.Failure); } }
internal static int InvokeCustomAction64(int sessionHandle, string entryPoint, long remotingDelegatePtr) { return(CustomActionProxy.InvokeCustomAction(sessionHandle, entryPoint, new IntPtr(remotingDelegatePtr))); }