diff --git a/Distribution/XmlSchemas/ExcelDna.DnaLibrary.xsd b/Distribution/XmlSchemas/ExcelDna.DnaLibrary.xsd
index e0f49645..1df66c66 100644
--- a/Distribution/XmlSchemas/ExcelDna.DnaLibrary.xsd
+++ b/Distribution/XmlSchemas/ExcelDna.DnaLibrary.xsd
@@ -206,6 +206,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
Images
set { _Images = value; }
}
+ private List _Files;
+ [XmlElement("File", typeof(DnaFile))]
+ public List Files
+ {
+ get { return _Files; }
+ set { _Files = value; }
+ }
+
private string dnaResolveRoot;
// Get projects explicit and implicitly present in the library
@@ -726,6 +734,40 @@ public Bitmap GetImage(string imageId)
return null;
}
+ public byte[] GetFileBytes(string fileId)
+ {
+ // TODO: Consider if this should be a Stream instead of a byte[]
+ // This would allow for larger files to be handled more efficiently.
+
+ // First check if fileId is in the DnaLibrary's File list.
+ // DOCUMENT: Case sensitive match.
+ foreach (DnaFile file in Files)
+ {
+ if (file.Name == fileId && file.Path != null)
+ {
+ byte[] fileBytes;
+ if (file.Path.StartsWith("packed:"))
+ {
+ string resourceName = file.Path.Substring(7);
+ fileBytes = ExcelIntegration.GetFileBytes(resourceName);
+ }
+ else
+ {
+ string filePath = ResolvePath(file.Path);
+ if (filePath == null)
+ {
+ // This is the file but we could not find it !?
+ Logger.Initialization.Warn("DnaLibrary.GetFile - For file {0} the path resolution failed: {1}", file.Name, file.Path);
+ return null;
+ }
+ fileBytes = File.ReadAllBytes(filePath);
+ }
+ return fileBytes;
+ }
+ }
+ return null;
+ }
+
}
//public class CustomUI : IXmlSerializable
diff --git a/Source/ExcelDna.Integration/Excel.cs b/Source/ExcelDna.Integration/Excel.cs
index 6a9ab7c8..c775e1fc 100644
--- a/Source/ExcelDna.Integration/Excel.cs
+++ b/Source/ExcelDna.Integration/Excel.cs
@@ -11,6 +11,8 @@
using System.IO;
using System.Reflection;
using System.Runtime.ExceptionServices;
+using System.Collections.Generic;
+using System.Linq;
namespace ExcelDna.Integration
{
@@ -782,6 +784,23 @@ public static bool SupportsDynamicArrays
}
}
#endregion
+
+ #region Packed Files
+ /// Returns the names of all the resources packed in the XLL.
+ /// An enumerable that contains the names of all the resources.
+ public static IEnumerable GetPackedFileNames()
+ {
+ return DnaLibrary.CurrentLibrary.Files.Select(f => f.Name);
+ }
+
+ /// Loads the specified resource from the XLL.
+ /// The case-sensitive name of the resource being requested.
+ /// The resource; or if the resource does not exist in the XLL.
+ public static byte[] GetPackedFileBytes(string name)
+ {
+ return DnaLibrary.CurrentLibrary.GetFileBytes(name);
+ }
+ #endregion
}
public class ExcelLimits
diff --git a/Source/ExcelDna.Integration/ExcelIntegration.cs b/Source/ExcelDna.Integration/ExcelIntegration.cs
index ba97364b..7ec8a374 100644
--- a/Source/ExcelDna.Integration/ExcelIntegration.cs
+++ b/Source/ExcelDna.Integration/ExcelIntegration.cs
@@ -183,6 +183,11 @@ internal static byte[] GetImageBytes(string imageName)
return _integrationHost.GetResourceBytes(imageName, 2);
}
+ internal static byte[] GetFileBytes(string fileName)
+ {
+ return _integrationHost.GetResourceBytes(fileName, 2);
+ }
+
internal static byte[] GetSourceBytes(string sourceName)
{
return _integrationHost.GetResourceBytes(sourceName, 3);
diff --git a/Source/ExcelDna.Integration/IIntegrationHost.cs b/Source/ExcelDna.Integration/IIntegrationHost.cs
index 8eb5fe09..ea421363 100644
--- a/Source/ExcelDna.Integration/IIntegrationHost.cs
+++ b/Source/ExcelDna.Integration/IIntegrationHost.cs
@@ -8,7 +8,7 @@ namespace ExcelDna.Integration
interface IIntegrationHost
{
XlCall.XlReturn TryExcelImpl(int xlFunction, out object result, params object[] parameters);
- byte[] GetResourceBytes(string resourceName, int type); // types: 0 - Assembly, 1 - Dna file, 2 - Image
+ byte[] GetResourceBytes(string resourceName, int type); // types: 0 - Assembly, 1 - Dna file, 2 - Image or File, 3 - Source, 4 - PDB
Assembly LoadFromAssemblyPath(string assemblyPath);
Assembly LoadFromAssemblyBytes(byte[] assemblyBytes, byte[] pdbBytes);
void RegisterMethods(List methods);
diff --git a/Source/ExcelDna.Integration/Reference.cs b/Source/ExcelDna.Integration/Reference.cs
index 688c2409..672f6fa0 100644
--- a/Source/ExcelDna.Integration/Reference.cs
+++ b/Source/ExcelDna.Integration/Reference.cs
@@ -53,7 +53,7 @@ public Reference(string path)
{
Path = path;
}
- }
+ }
[Serializable]
[XmlType(AnonymousType = true)]
@@ -73,4 +73,22 @@ public Image()
}
}
+ [Serializable]
+ [XmlType(AnonymousType = true)]
+ public class DnaFile
+ {
+ [XmlAttribute]
+ public string Name;
+
+ [XmlAttribute]
+ public string Path;
+
+ [XmlAttribute]
+ public bool Pack;
+
+ public DnaFile()
+ {
+ }
+ }
+
}
diff --git a/Source/ExcelDna.PackedResources/ExcelDnaPack.cs b/Source/ExcelDna.PackedResources/ExcelDnaPack.cs
index 012f1a33..72a4aa9d 100644
--- a/Source/ExcelDna.PackedResources/ExcelDnaPack.cs
+++ b/Source/ExcelDna.PackedResources/ExcelDnaPack.cs
@@ -402,6 +402,31 @@ static private byte[] PackDnaLibrary(string dnaPath, byte[] dnaContent, string d
}
}
}
+ foreach (DnaFile file in dna.Files)
+ {
+ if (file.Pack)
+ {
+ string path = dna.ResolvePath(file.Path);
+ if (path == null)
+ {
+ var format = " ~~> ERROR: File path {0} NOT RESOLVED.";
+ errorMessage = string.Format(format, file.Path);
+ buildLogger.Error(typeof(ExcelDnaPack), format, file.Path);
+ throw new InvalidOperationException(errorMessage);
+ }
+ if (filesToPublish == null)
+ {
+ string name = Path.GetFileNameWithoutExtension(path).ToUpperInvariant() + "_" + lastPackIndex++ + Path.GetExtension(path).ToUpperInvariant();
+ byte[] fileBytes = File.ReadAllBytes(path);
+ ru.AddFile(fileBytes, name, ResourceHelper.TypeName.FILE, null, compress, multithreading);
+ file.Path = "packed:" + name;
+ }
+ else
+ {
+ filesToPublish.Add(path);
+ }
+ }
+ }
foreach (Project project in dna.Projects)
{
foreach (SourceItem source in project.SourceItems)
diff --git a/Source/ExcelDna.PackedResources/ResourceHelper.cs b/Source/ExcelDna.PackedResources/ResourceHelper.cs
index d79fa113..a32e617e 100644
--- a/Source/ExcelDna.PackedResources/ResourceHelper.cs
+++ b/Source/ExcelDna.PackedResources/ResourceHelper.cs
@@ -25,6 +25,7 @@ internal enum TypeName
SOURCE = 3,
PDB = 4,
NATIVE_LIBRARY = 5,
+ FILE = 6,
}
// TODO: Learn about locales