// This is the helper macro that runs (on the main thread)
 void SyncMacro(double _unused_)
 {
     // Check for timer and disable
     if (_timerId != 0)
     {
         KillTimer(new HandleRef(_syncWindow, _syncWindow.Handle), _timerId);
         _timerId = 0; // No race condition between the check and the reset here, since we're always on the main thread.
     }
     // Run everything currently in the queue
     _isRunningMacros = true;
     while (_isRunningMacros)
     {
         SendOrPostCallback work  = null;
         object             state = null;
         lock (_sendOrPostLock)
         {
             _isRunningMacros = _postCallbacks.Count > 0;
             if (_isRunningMacros)
             {
                 work  = _postCallbacks.Dequeue();
                 state = _postStates.Dequeue();
             }
             else
             {
                 // set flag that we need to post again for work
                 // and exit
                 _syncPosted = false;
                 return;
             }
         }
         try
         {
             work(state);
         }
         catch (Exception ex)
         {
             UnhandledExceptionHandler handler = ExcelIntegration.GetRegisterUnhandledExceptionHandler();
             if (handler != null)
             {
                 try
                 {
                     handler(ex);
                 }
                 catch (Exception uehex)
                 {
                     Logger.Runtime.Error(ex, "Unhandled exception in async delegate call.");
                     Logger.Runtime.Error(uehex, "Unhandled exception in UnhandledExceptionHandler after async delegate call.");
                 }
             }
             else
             {
                 Logger.Runtime.Error(ex, "Unhandled exception in async delegate call.");
             }
         }
     }
 }
Beispiel #2
0
        // Only called for the Root DnaLibrary.
        internal void AutoOpen()
        {
            // Register special RegistrationInfo function
            RegistrationInfo.Register();
            SynchronizationManager.Install(true);
            // Register my Methods - should this also go into the delayed call?
            ExcelIntegration.RegisterMethods(_methods);

            // We defer the rest of the load until we have an Application object...
            ExcelAsyncUtil.QueueAsMacro(AutoOpenImpl);
        }
Beispiel #3
0
        public Bitmap GetImage(string imageId)
        {
            // We expect these to be small images.

            // First check if imageId is in the DnaLibrary's Image list.
            // DOCUMENT: Case sensitive match.
            foreach (Image image in Images)
            {
                if (image.Name == imageId && image.Path != null)
                {
                    byte[] imageBytes = null;
                    System.Drawing.Image imageLoaded;
                    if (image.Path.StartsWith("packed:"))
                    {
                        string resourceName = image.Path.Substring(7);
                        imageBytes = ExcelIntegration.GetImageBytes(resourceName);
                    }
                    else
                    {
                        string imagePath = ResolvePath(image.Path);
                        if (imagePath == null)
                        {
                            // This is the image but we could not find it !?
                            Logger.Initialization.Warn("DnaLibrary.GetImage - For image {0} the path resolution failed: {1}", image.Name, image.Path);
                            return(null);
                        }
                        imageBytes = File.ReadAllBytes(imagePath);
                    }
                    using (MemoryStream ms = new MemoryStream(imageBytes, false))
                    {
                        imageLoaded = System.Drawing.Image.FromStream(ms);
                        if (imageLoaded is Bitmap)
                        {
                            return((Bitmap)imageLoaded);
                        }
                        Logger.Initialization.Warn("DnaLibrary.GetImage - Image {0} read from {1} was not a bitmap!?", image.Name, image.Path);
                    }
                }
            }
            return(null);
        }
Beispiel #4
0
        internal static void InitializeRootLibrary(string xllPath)
        {
            // Loads the primary .dna library
            // Load sequence is:
            // 1. Look for a packed .dna file named "__MAIN__" in the .xll.
            // 2. Look for the .dna file in the same directory as the .xll file, with the same name and extension .dna.

            // CAREFUL: Sequence here is fragile - this is the first place where we start logging
            _XllPath         = xllPath;
            _xllPathPathInfo = new FileInfo(xllPath);
            Logging.LogDisplay.CreateInstance();
            Logger.Initialization.Verbose("Enter DnaLibrary.InitializeRootLibrary");
            byte[] dnaBytes = ExcelIntegration.GetDnaFileBytes("__MAIN__");
            if (dnaBytes != null)
            {
                Logger.Initialization.Verbose("Got Dna file from resources.");
                string pathResolveRoot = Path.GetDirectoryName(DnaLibrary.XllPath);
                rootLibrary = LoadFrom(dnaBytes, pathResolveRoot);
                // ... would have displayed error and returned null if there was an error.
            }
            else
            {
                Logger.Initialization.Verbose("No Dna file in resources - looking for file.");
                // No packed .dna file found - load from a .dna file.
                string dnaFileName = Path.ChangeExtension(XllPath, ".dna");
                rootLibrary = LoadFrom(dnaFileName);
                // ... would have displayed error and returned null if there was an error.
            }

            // If there have been problems, ensure that there is at lease some current library.
            if (rootLibrary == null)
            {
                Logger.Initialization.Error("No Dna Library found.");
                rootLibrary = new DnaLibrary();
            }

            rootLibrary.Initialize();
            Logger.Initialization.Verbose("Exit DnaLibrary.Initialize");
        }
Beispiel #5
0
        internal List <ExportedAssembly> GetAssemblies(string pathResolveRoot, DnaLibrary dnaLibrary)
        {
            List <ExportedAssembly> list = new List <ExportedAssembly>();

            try
            {
                string realPath = Path;
                if (Path.StartsWith("packed:"))
                {
                    // The ExternalLibrary is packed.
                    // We'll have to load it from resources.
                    string resourceName = Path.Substring(7);
                    if (Path.EndsWith(".DNA", StringComparison.OrdinalIgnoreCase))
                    {
                        byte[]     dnaContent = ExcelIntegration.GetDnaFileBytes(resourceName);
                        DnaLibrary lib        = DnaLibrary.LoadFrom(dnaContent, pathResolveRoot);
                        if (lib == null)
                        {
                            Logger.Initialization.Error("External library could not be registered - Path: {0}\r\n - Packed DnaLibrary could not be loaded", Path);
                            return(list);
                        }

                        return(lib.GetAssemblies(pathResolveRoot));
                    }
                    else
                    {
                        // DOCUMENT: TypeLibPath which is a resource in a library is denoted as fileName.dll\4
                        // For packed assemblies, we set TypeLibPath="packed:2"
                        string typeLibPath = null;
                        if (!string.IsNullOrEmpty(TypeLibPath) && TypeLibPath.StartsWith("packed:"))
                        {
                            typeLibPath = DnaLibrary.XllPath + @"\" + TypeLibPath.Substring(7);
                        }

                        // It would be nice to check here whether the assembly is loaded already.
                        // But because of the name mangling in the packing we can't easily check.

                        // So we make the following assumptions:
                        // 1. Packed assemblies won't also be loadable from files (else they might be loaded twice)
                        // 2. ExternalLibrary loads will happen before reference loads via AssemblyResolve.
                        // Under these assumptions we should not have assemblies loaded more than once,
                        // even if not checking here.
                        byte[]   rawAssembly = ExcelIntegration.GetAssemblyBytes(resourceName);
                        byte[]   rawPdb      = ExcelIntegration.GetPdbBytes(resourceName);
                        Assembly assembly    = ExcelIntegration.LoadFromAssemblyBytes(rawAssembly, rawPdb);
                        list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, typeLibPath, dnaLibrary));
                        return(list);
                    }
                }
                if (Uri.IsWellFormedUriString(Path, UriKind.Absolute))
                {
                    // Here is support for loading ExternalLibraries from http.
                    Uri uri = new Uri(Path, UriKind.Absolute);
                    if (uri.IsUnc)
                    {
                        realPath = uri.LocalPath;
                        // Will continue to load later with the regular file load part below...
                    }
                    else
                    {
                        string scheme = uri.Scheme.ToLowerInvariant();
                        if (scheme != "http" && scheme != "file" && scheme != "https")
                        {
                            Logger.Initialization.Error("The ExternalLibrary path {0} is not a valid Uri scheme.", Path);
                            return(list);
                        }
                        else
                        {
                            if (uri.AbsolutePath.EndsWith("dna", StringComparison.InvariantCultureIgnoreCase))
                            {
                                DnaLibrary lib = DnaLibrary.LoadFrom(uri);
                                if (lib == null)
                                {
                                    Logger.Initialization.Error("External library could not be registered - Path: {0} - DnaLibrary could not be loaded" + Path);
                                    return(list);
                                }
                                // CONSIDER: Should we add a resolve story for .dna files at Uris?
                                return(lib.GetAssemblies(null)); // No explicit resolve path
                            }
                            else
                            {
                                // Load as a regular assembly - TypeLib not supported.
                                Assembly assembly = ExcelIntegration.LoadFromAssemblyPath(Path);
                                list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, null, dnaLibrary));
                                return(list);
                            }
                        }
                    }
                }
                // Keep trying with the current value of realPath.
                string resolvedPath = DnaLibrary.ResolvePath(realPath, pathResolveRoot);
                if (resolvedPath == null)
                {
                    Logger.Initialization.Error("External library could not be registered - Path: {0} - The library could not be found at this location" + Path);
                    return(list);
                }
                if (System.IO.Path.GetExtension(resolvedPath).Equals(".DNA", StringComparison.OrdinalIgnoreCase))
                {
                    // Load as a DnaLibrary
                    DnaLibrary lib = DnaLibrary.LoadFrom(resolvedPath);
                    if (lib == null)
                    {
                        Logger.Initialization.Error("External library could not be registered - Path: {0} - DnaLibrary could not be loaded" + Path);
                        return(list);
                    }

                    string pathResolveRelative = System.IO.Path.GetDirectoryName(resolvedPath);
                    return(lib.GetAssemblies(pathResolveRelative));
                }
                else
                {
                    Assembly assembly;
                    // Load as a regular assembly
                    // First check if it is already loaded (e.g. as a reference from another assembly)
                    // DOCUMENT: Some cases might still have assemblies loaded more than once.
                    // E.g. for an assembly that is both ExternalLibrary and references from another assembly,
                    // having the assembly LoadFromBytes and in the file system would load it twice,
                    // because LoadFromBytes here happens before the .NET loaders assembly resolution.
                    string assemblyName = System.IO.Path.GetFileNameWithoutExtension(resolvedPath);
                    assembly = GetAssemblyIfLoaded(assemblyName);
                    if (assembly == null)
                    {
                        // Really have to load it.
                        if (LoadFromBytes)
                        {
                            // We need to be careful here to not re-load the assembly if it had already been loaded,
                            // e.g. as a dependency of an assembly loaded earlier.
                            // In that case we won't be able to have the library 'LoadFromBytes'.
                            byte[] bytes    = File.ReadAllBytes(resolvedPath);
                            byte[] pdbBytes = null;

                            string pdbPath = System.IO.Path.ChangeExtension(resolvedPath, "pdb");
                            if (File.Exists(pdbPath))
                            {
                                pdbBytes = File.ReadAllBytes(pdbPath);
                            }
                            assembly = ExcelIntegration.LoadFromAssemblyBytes(bytes, pdbBytes);
                        }
                        else
                        {
                            assembly = ExcelIntegration.LoadFromAssemblyPath(resolvedPath);
                        }
                    }
                    string resolvedTypeLibPath = null;
                    if (!string.IsNullOrEmpty(TypeLibPath))
                    {
                        resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, pathResolveRoot); // null is unresolved
                        if (resolvedTypeLibPath == null)
                        {
                            resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, System.IO.Path.GetDirectoryName(resolvedPath));
                        }
                    }
                    else
                    {
                        // Check for .tlb with same name next to resolvedPath
                        string tlbCheck = System.IO.Path.ChangeExtension(resolvedPath, "tlb");
                        if (System.IO.File.Exists(tlbCheck))
                        {
                            resolvedTypeLibPath = tlbCheck;
                        }
                    }
                    list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, resolvedTypeLibPath, dnaLibrary));
                    return(list);
                }
            }
            catch (Exception e)
            {
                // Assembly could not be loaded.
                Logger.Initialization.Error(e, "External library could not be registered - Path: {0}", Path);
                return(list);
            }
        }
Beispiel #6
0
 public static void RegisterUnhandledExceptionHandler(UnhandledExceptionHandler h)
 {
     ExcelIntegration.RegisterUnhandledExceptionHandler(h);
 }
Beispiel #7
0
 public static void RegisterMethods(List <MethodInfo> methods)
 {
     ExcelIntegration.RegisterMethods(methods);
 }
Beispiel #8
0
        public List <string> GetReferencePaths(string pathResolveRoot, CodeDomProvider provider)
        {
            List <string> refPaths = new List <string>();

            if (References != null)
            {
                foreach (Reference rf in References)
                {
                    bool isResolved = false;
                    if (rf.Path != null)
                    {
                        if (rf.Path.StartsWith("packed:"))
                        {
                            string assName = rf.Path.Substring(7);
                            string assPath = Path.GetTempFileName();
                            tempAssemblyPaths.Add(assPath);
                            File.WriteAllBytes(assPath, ExcelIntegration.GetAssemblyBytes(assName));
                            refPaths.Add(assPath);
                            isResolved = true;
                        }
                        else
                        {
                            // Call ResolvePath - check relative to pathResolveRoot and in framework directory.
                            string refPath = DnaLibrary.ResolvePath(rf.Path, pathResolveRoot);
                            if (!string.IsNullOrEmpty(refPath))
                            {
                                refPaths.Add(refPath);
                                isResolved = true;
                            }
                        }
                    }
                    if (!isResolved && rf.Name != null)
                    {
                        // Try to resolve by Name
                        #pragma warning disable 0618
                        Assembly refAssembly = Assembly.LoadWithPartialName(rf.Name);
                        #pragma warning restore 0618
                        if (refAssembly != null)
                        {
                            if (!string.IsNullOrEmpty(refAssembly.Location))
                            {
                                refPaths.Add(refAssembly.Location);
                                isResolved = true;
                            }
                        }
                    }
                    if (!isResolved)
                    {
                        // Must have been loaded by us from the packing....?
                        Logger.DnaCompilation.Error("Assembly resolve failure - Reference Name: {0}, Path: {1}", rf.Name, rf.Path);
                    }
                }
            }
            if (DefaultReferences)
            {
                // CONSIDER: Should these be considered more carefully? I'm just putting in what the default templates in Visual Studio 2010 put in.
                refPaths.Add("System.dll");
                refPaths.Add("System.Data.dll");
                refPaths.Add("System.Xml.dll");
                if (Environment.Version.Major >= 4)
                {
                    refPaths.Add("System.Core.dll");
                    refPaths.Add("System.Data.DataSetExtensions.dll");
                    refPaths.Add("System.Xml.Linq.dll");
                    if (provider is Microsoft.CSharp.CSharpCodeProvider)
                    {
                        refPaths.Add("Microsoft.CSharp.dll");
                    }
                }
            }
            // DOCUMENT: Reference to the xll is always added
            // Sort out "ExcelDna.Integration.dll" copy which causes problems
            // TODO: URGENT: Revisit this... (don't know what to do yet - maybe full AssemblyName).
            string location = Assembly.GetExecutingAssembly().Location;
            if (location != "")
            {
                refPaths.Add(location);
            }
            else
            {
                string assPath = Path.GetTempFileName();
                tempAssemblyPaths.Add(assPath);
                File.WriteAllBytes(assPath, ExcelIntegration.GetAssemblyBytes("EXCELDNA.INTEGRATION"));
                refPaths.Add(assPath);
            }

            Logger.DnaCompilation.Verbose("Compiler References: ");
            foreach (string rfPath in refPaths)
            {
                Logger.DnaCompilation.Verbose("    " + rfPath);
            }

            return(refPaths);
        }
 public override void RegisterMethods(List <MethodInfo> methods)
 {
     ExcelIntegration.RegisterMethods(methods);
 }
 public override void RegisterUnhandledExceptionHandler(UnhandledExceptionHandler exceptionHandler)
 {
     ExcelIntegration.RegisterUnhandledExceptionHandler(exceptionHandler);
 }
Beispiel #11
0
        // Calls the Excel-DNA UnhandledExceptionHandler (which by default returns #VALUE to Excel).
        public override bool SetException(Exception exception)
        {
            object result = ExcelIntegration.HandleUnhandledException(exception);

            return(SetResult(result));
        }
Beispiel #12
0
 static int CallPenHelper(int wCode, ref XlCall.FmlaInfo fmlaInfo)
 {
     return(ExcelIntegration.LPenHelper(XlCall.xlGetFmlaInfo, ref fmlaInfo));
 }