static readonly CultureInfo _enUsCulture = new CultureInfo(1033); // Don't know if this is useful... // Invoke Application.Run to run a macro // Returns true if it ran OK, false if not and we should retry static bool COMRunMacro(string macroName) { try { // If busy editing, don't even try to call Application.Run. if (IsInFormulaEditMode()) { return(false); } object xlApp = ExcelDnaUtil.GetApplicationNotProtectedNoThrow(); if (xlApp == null) { // Some possibilities that get us here: // * Can't get Application object at all - first time we're trying is here, no workbook open and hence C API is needed but not available // * Excel is shutting down (would have abandoned in the past, now we keep re-trying) return(false); } Type appType = xlApp.GetType(); // Now try Application.Run(macroName) if we are still alive. object result = appType.InvokeMember("Run", BindingFlags.InvokeMethod, null, xlApp, new object[] { macroName, 0.0 }, _enUsCulture); // Sometimes (e.g. when the paste live preview feature is active) Application.Run returns the integer value for E_FAIL, // and not a COM Error that is converted to an exception. if (!result.Equals(0.0)) // We expect our "void" macro to just return 0.0. { #if DEBUG // Some extra checks to see if we can understand the return values better if (!(result is int)) { Logger.Registration.Error("Unexpected return type from Application.Run(\"SyncMacro_...\") - " + result); } else { if ((int)result != E_FAIL && (int)result != E_NA) { Logger.Registration.Error("Unexpected return value from Application.Run(\"SyncMacro_...\") - " + result); } } #endif return(false); } return(true); } catch (TargetInvocationException tie) { // Deal with the COM exception that we get if the Application object does not allow us to call 'Run' right now. COMException cex = tie.InnerException as COMException; if (cex != null && IsRetry(cex)) { return(false); } // Unexpected error - very bad - we abandon the whole QueueAsMacro plan forever - the exception is handled higher up and logged throw; } }
// TODO: Check that this does not happen in a 'function' context. internal static void Install() { if (!ExcelDnaUtil.IsMainThread()) { throw new InvalidOperationException("SynchronizationManager must be installed from the main Excel thread. Ensure that ExcelAsyncUtil.Initialize() is called from AutoOpen() or a macro on the main Excel thread."); } if (_syncWindow == null) { _syncWindow = new SynchronizationWindow(); } _installCount++; }
internal static void Uninstall() { if (!ExcelDnaUtil.IsMainThread()) { throw new InvalidOperationException("SynchronizationManager must be uninstalled from the main Excel thread. Ensure that ExcelAsyncUtil.Uninitialize() is called from AutoOpen() or a macro on the main Excel thread."); } _installCount--; if (_installCount == 0 && _syncWindow != null) { _syncWindow.Dispose(); _syncWindow = null; } }
// Only called for the Root DnaLibrary. internal void AutoOpen() { SynchronizationManager.Install(true); if (ExcelDnaUtil.GetApplicationNotProtectedNoThrow() != null) { // Proceed without undue delay AutoOpenImpl(); } else { // Some possibilities that get us here: // * Can't get Application object at all - first time we're trying is here, no workbook open and hence C API is needed but not available // * Excel is shutting down (would have abandoned in the past, now we keep re-trying) // We defer the rest of the load until we have an Application object... ExcelAsyncUtil.QueueAsMacro(AutoOpenImpl); } }
// Called via Reflection from Loader internal static void Initialize(string xllPath) { ExcelDnaUtil.Initialize(); // Set up window handle Logging.TraceLogger.Initialize(); DnaLibrary.InitializeRootLibrary(xllPath); }
// Name of the Registration Helper function, registered in ExcelIntegration.RegisterRegistrationInfo static string RegistrationInfoName(string xllPath) { return("RegistrationInfo_" + ExcelDnaUtil.GuidFromXllPath(xllPath).ToString("N")); }
public override bool IsInFunctionWizard() { return(ExcelDnaUtil.IsInFunctionWizard()); }
public static bool IsInFunctionWizard() { return(ExcelDnaUtil.IsInFunctionWizard()); }
internal static void Initialize() { ExcelDnaUtil.Initialize(); DnaLibrary.Initialize(); }