Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Package/Excel-DNA.Interop/Excel-DNA.Interop.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Excel-DNA.Interop</id>
<version>15.0.1</version>
<version>16.0.0</version>
<title>Excel-DNA - Primary Interop Assemblies for Excel</title>
<authors>Excel-DNA Contributors</authors>
<owners>excel-dna</owners>
<projectUrl>http://excel-dna.net</projectUrl>
<repository type="git" url="https://github.com/Excel-DNA/ExcelDna" />
<icon>images\ExcelDna-nu.png</icon>
<license type="expression">MIT</license>
<readme>README.md</readme>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>This package is deprecated, and has been replaced by ExcelDna.Interop - https://www.nuget.org/packages/ExcelDna.Interop/.</description>
<summary>Provides a selection of Excel Primary Interop Assemblies</summary>
<tags>Excel Interop PIA ExcelDna</tags>
<dependencies>
<dependency id="ExcelDna.Interop" version="[15.0.1]" />
<dependency id="ExcelDna.Interop" version="[16.0.0]" />
</dependencies>
</metadata>
<files>
<file src="..\images\ExcelDna-nu.png" target="images\" />
<file src="README.md" target="" />
</files>
</package>
5 changes: 5 additions & 0 deletions Package/Excel-DNA.Interop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Excel-DNA.Interop

This package is deprecated. Use [ExcelDna.Interop](https://www.nuget.org/packages/ExcelDna.Interop/) instead.

The dependency on `ExcelDna.Interop` supplies the Microsoft Office primary interop assemblies used by Excel-DNA add-ins.
2 changes: 2 additions & 0 deletions Package/ExcelDna.Interop.Dao/ExcelDna.Interop.Dao.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<projectUrl>http://excel-dna.net</projectUrl>
<icon>images\ExcelDna-nu.png</icon>
<license type="expression">MIT</license>
<readme>README.md</readme>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Provides a local copy of the Microsoft.Office.Interop.Access.Dao.dll primary interop assembly from Microsoft Office.</description>
<summary>Provides the Primary Interop Assembly for the Access DAO library.</summary>
Expand All @@ -24,5 +25,6 @@
<file src="lib\Microsoft.Office.Interop.Access.Dao.dll" target="lib\net6.0-windows7.0\" />
<file src="build\ExcelDna.Interop.Dao.targets" target="build" />
<file src="..\images\ExcelDna-nu.png" target="images\" />
<file src="README.md" target="" />
</files>
</package>
7 changes: 7 additions & 0 deletions Package/ExcelDna.Interop.Dao/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ExcelDna.Interop.Dao

This package provides a local copy of the `Microsoft.Office.Interop.Access.Dao.dll` primary interop assembly for the Microsoft Access DAO library.

The assembly is available for .NET Framework 4.5.2 and `net6.0-windows7.0` projects. The package configures C# and Visual Basic projects to embed the interop types and not copy the assembly to the output directory. F# projects are excluded from that build behavior.

For Excel-DNA documentation, see [excel-dna.net](https://excel-dna.net/).
2 changes: 2 additions & 0 deletions Package/ExcelDna.Interop/ExcelDna.Interop.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<projectUrl>http://excel-dna.net</projectUrl>
<icon>images\ExcelDna-nu.png</icon>
<license type="expression">MIT</license>
<readme>README.md</readme>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Provides a local copy of the Primary Interop Assemblies from Microsoft Office: Microsoft.Office.Interop.Excel.dll, Office.dll, Microsoft.Vbe.Interop.dll.</description>
<summary>Provides a selection of Excel Primary Interop Assemblies</summary>
Expand All @@ -28,5 +29,6 @@
<file src="lib\office.dll" target="lib\net6.0-windows7.0" />
<file src="build\ExcelDna.Interop.targets" target="build\" />
<file src="..\images\ExcelDna-nu.png" target="images\" />
<file src="README.md" target="" />
</files>
</package>
11 changes: 11 additions & 0 deletions Package/ExcelDna.Interop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ExcelDna.Interop

This package provides local copies of these Microsoft Office primary interop assemblies:

- `Microsoft.Office.Interop.Excel.dll`
- `Microsoft.Vbe.Interop.dll`
- `office.dll`

The assemblies are available for .NET Framework 4.5.2 and `net6.0-windows7.0` projects. The package configures C# and Visual Basic projects to embed the interop types and not copy the assemblies to the output directory. F# projects are excluded from that build behavior.

For Excel-DNA documentation, see [excel-dna.net](https://excel-dna.net/).
6 changes: 3 additions & 3 deletions Package/package-interop.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ if not exist "%outputPath%" mkdir "%outputPath%"

echo on

nuget.exe pack "%basePath%\Excel-DNA.Interop\Excel-DNA.Interop.nuspec" -BasePath "%basePath%\Excel-DNA.Interop" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive -Prop ExcelDnaVersion="%ExcelDnaVersion%"
"%basePath%\nuget.exe" pack "%basePath%\Excel-DNA.Interop\Excel-DNA.Interop.nuspec" -BasePath "%basePath%\Excel-DNA.Interop" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive -Prop ExcelDnaVersion="%ExcelDnaVersion%"
@if errorlevel 1 goto end

nuget.exe pack "%basePath%\ExcelDna.Interop\ExcelDna.Interop.nuspec" -BasePath "%basePath%\ExcelDna.Interop" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive
"%basePath%\nuget.exe" pack "%basePath%\ExcelDna.Interop\ExcelDna.Interop.nuspec" -BasePath "%basePath%\ExcelDna.Interop" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive
@if errorlevel 1 goto end

nuget.exe pack "%basePath%\ExcelDna.Interop.Dao\ExcelDna.Interop.Dao.nuspec" -BasePath "%basePath%\ExcelDna.Interop.Dao" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive
"%basePath%\nuget.exe" pack "%basePath%\ExcelDna.Interop.Dao\ExcelDna.Interop.Dao.nuspec" -BasePath "%basePath%\ExcelDna.Interop.Dao" -OutputDirectory "%outputPath%" -Verbosity detailed -NonInteractive
@if errorlevel 1 goto end

:end
6 changes: 3 additions & 3 deletions Package/push-interop.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ set outputPath=%basePath%\nupkg

if not exist "%outputPath%" mkdir "%outputPath%"

nuget.exe push "%outputPath%\Excel-DNA.Interop.15.0.1.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
nuget.exe push "%outputPath%\Excel-DNA.Interop.16.0.0.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
@if errorlevel 1 goto end

nuget.exe push "%outputPath%\ExcelDna.Interop.15.0.1.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
nuget.exe push "%outputPath%\ExcelDna.Interop.16.0.0.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
@if errorlevel 1 goto end

nuget.exe push "%outputPath%\ExcelDna.Interop.Dao.15.0.1.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
nuget.exe push "%outputPath%\ExcelDna.Interop.Dao.16.0.0.nupkg" -Source https://api.nuget.org/v3/index.json -Verbosity detailed -NonInteractive
@if errorlevel 1 goto end

:end
1 change: 1 addition & 0 deletions Source/ExcelDna.Integration/ComInterop/ComServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ internal static HRESULT DllGetClassObject(CLSID clsid, IID iid, out IntPtr ppunk
ComWrappers cw = new System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers();
nint ptr = cw.GetOrCreateComInterfaceForObject(factory, CreateComInterfaceFlags.None);
HRESULT hrQI = Marshal.QueryInterface(ptr, in iid, out ppunk);
Marshal.Release(ptr);
#else
IntPtr punkFactory = Marshal.GetIUnknownForObject(factory);
HRESULT hrQI = Marshal.QueryInterface(punkFactory, ref iid, out ppunk);
Expand Down
17 changes: 11 additions & 6 deletions Source/ExcelDna.Integration/ComInterop/DummyComAddIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,29 @@ namespace ExcelDna.Integration.ComInterop
[GeneratedComClass]
internal partial class DummyComAddIn : Generator.Interfaces.IDTExtensibility2
{
private const int S_OK = 0;
private const int E_NOTIMPL = unchecked((int)0x80004001);

public int GetTypeInfoCount(out uint pctinfo)
{
throw new NotImplementedException();
pctinfo = 0;
return S_OK;
}

public int GetTypeInfo(uint iTInfo, uint lcid, out nint ppTInfo)
{
throw new NotImplementedException();
ppTInfo = 0;
return E_NOTIMPL;
}

public int GetIDsOfNames(Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] int[] rgDispId)
public int GetIDsOfNames(in Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] int[] rgDispId)
{
throw new NotImplementedException();
return E_NOTIMPL;
}

public int Invoke(int dispIdMember, Guid riid, uint lcid, INVOKEKIND wFlags, [MarshalUsing(typeof(Generator.Interfaces.DispParamsMarshaller))] in Generator.Interfaces.DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
public int Invoke(int dispIdMember, in Guid riid, uint lcid, ushort wFlags, [MarshalUsing(typeof(Generator.Interfaces.DispParamsMarshaller))] in Generator.Interfaces.DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
{
throw new NotImplementedException();
return E_NOTIMPL;
}

#region IDTExtensibility2 interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace ExcelDna.Integration.ComInterop.Generator
[GeneratedComClass]
internal partial class ExcelObserverRtdServer : Rtd.ExcelObserverRtdServer, IRtdServer
{
private const int S_OK = 0;
private const int E_NOTIMPL = unchecked((int)0x80004001);

private Dispatcher dispatcher;

public ExcelObserverRtdServer()
Expand All @@ -29,22 +32,24 @@ public ExcelObserverRtdServer()
// IDispatch:
public int GetTypeInfoCount(out uint pctinfo)
{
throw new NotImplementedException();
pctinfo = 0;
return S_OK;
}

public int GetTypeInfo(uint iTInfo, uint lcid, out nint ppTInfo)
{
throw new NotImplementedException();
ppTInfo = 0;
return E_NOTIMPL;
}

public int GetIDsOfNames(Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] int[] rgDispId)
public int GetIDsOfNames(in Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] int[] rgDispId)
{
dispatcher.GetIDsOfNames(rgszNames, rgDispId);

return 0;
}

public int Invoke(int dispIdMember, Guid riid, uint lcid, INVOKEKIND wFlags, [MarshalUsing(typeof(DispParamsMarshaller))] in DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
public int Invoke(int dispIdMember, in Guid riid, uint lcid, ushort wFlags, [MarshalUsing(typeof(DispParamsMarshaller))] in DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
{
dispatcher.Invoke(dispIdMember, pDispParams, pVarResult);

Expand Down
33 changes: 26 additions & 7 deletions Source/ExcelDna.Integration/ComInterop/Generator/ExcelRibbon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace ExcelDna.Integration.ComInterop.Generator
[GeneratedComClass]
internal partial class ExcelRibbon : ExcelComAddIn, Interfaces.IDTExtensibility2, Interfaces.IRibbonExtensibility
{
private const int S_OK = 0;
private const int E_NOTIMPL = unchecked((int)0x80004001);
private const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006);

private MethodInfo[] methods;
private CustomUI.IExcelRibbon customRibbon;

Expand All @@ -26,23 +30,29 @@ public ExcelRibbon(ITypeHelper t)

public int GetTypeInfoCount(out uint pctinfo)
{
throw new NotImplementedException();
pctinfo = 0;
return S_OK;
}

public int GetTypeInfo(uint iTInfo, uint lcid, out nint ppTInfo)
{
throw new NotImplementedException();
ppTInfo = 0;
return E_NOTIMPL;
}

public int GetIDsOfNames(Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] int[] rgDispId)
public int GetIDsOfNames(in Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames, uint cNames, uint lcid, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] int[] rgDispId)
{
bool foundAll = true;
for (int i = 0; i < cNames; ++i)
{
rgDispId[i] = (rgszNames[i] == "LoadImage") ? methods.Length : Array.FindIndex(methods, m => m?.Name == rgszNames[i]);
foundAll &= rgDispId[i] >= 0;
}

return 0;
return foundAll ? S_OK : DISP_E_UNKNOWNNAME;
}

public int Invoke(int dispIdMember, Guid riid, uint lcid, INVOKEKIND wFlags, [MarshalUsing(typeof(Generator.Interfaces.DispParamsMarshaller))] in Generator.Interfaces.DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
public int Invoke(int dispIdMember, in Guid riid, uint lcid, ushort wFlags, [MarshalUsing(typeof(Generator.Interfaces.DispParamsMarshaller))] in Generator.Interfaces.DispParams pDispParams, nint pVarResult, nint pExcepInfo, nint puArgErr)
{
try
{
Expand Down Expand Up @@ -139,8 +149,17 @@ public virtual void OnBeginShutdown(ref Generator.Interfaces.SafeArray custom)

public int GetCustomUI([MarshalAs(UnmanagedType.BStr)] string RibbonID, [MarshalAs(UnmanagedType.BStr)] out string result)
{
result = customRibbon.GetCustomUI(RibbonID);
return 0;
try
{
result = customRibbon.GetCustomUI(RibbonID);
return S_OK;
}
catch (Exception ex)
{
ExcelDna.Logging.Logger.ComAddIn.Error(ex, "Ribbon GetCustomUI failed");
result = string.Empty;
return E_NOTIMPL;
}
}
#endregion

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
#if COM_GENERATED

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace ExcelDna.Integration.ComInterop.Generator.Interfaces
{
internal static class ArrayMarshaller
{
public unsafe static nint ArrayToPtr<T>(T[] str)
public static nint ArrayToPtr<T>(T[] values)
{
return (nint)Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(str));
if (values == null || values.Length == 0)
return nint.Zero;

int size = Marshal.SizeOf<T>();
nint result = Marshal.AllocHGlobal(size * values.Length);
for (int i = 0; i < values.Length; ++i)
Marshal.StructureToPtr(values[i], result + i * size, false);

return result;
}

public static void FreePtr(nint ptr)
{
if (ptr != nint.Zero)
Marshal.FreeHGlobal(ptr);
}

public static T[] PtrToArray<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(nint str, int len)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ internal static class DispParamsMarshaller
{
public static unsafe DispParamsNative ConvertToUnmanaged(DispParams managed)
{
int* rgdispidNamedArgs = null;
if (managed.rgdispidNamedArgs != 0)
{
rgdispidNamedArgs = (int*)Marshal.AllocHGlobal(sizeof(int));
*rgdispidNamedArgs = managed.rgdispidNamedArgs;
}

return new DispParamsNative
{
cArgs = managed.cArgs,
cNamedArgs = managed.cNamedArgs,
rgdispidNamedArgs = managed.rgdispidNamedArgs != 0 ? &managed.rgdispidNamedArgs : null,
rgdispidNamedArgs = rgdispidNamedArgs,
rgvarg =
managed.rgvarg != null
? ArrayMarshaller.ArrayToPtr(managed.rgvarg.Reverse().Select(VariantMarshaller.ConvertToUnmanaged).ToArray())
Expand All @@ -39,6 +46,22 @@ public static unsafe DispParams ConvertToManaged(DispParamsNative unmanaged)
};
}

public static unsafe void Free(DispParamsNative unmanaged)
{
if (unmanaged.rgvarg != 0)
{
int size = Marshal.SizeOf<VariantNative>();
for (int i = 0; i < unmanaged.cArgs; ++i)
{
VariantMarshaller.Free(Marshal.PtrToStructure<VariantNative>(unmanaged.rgvarg + i * size));
}
ArrayMarshaller.FreePtr(unmanaged.rgvarg);
}

if (unmanaged.rgdispidNamedArgs != null)
Marshal.FreeHGlobal((nint)unmanaged.rgdispidNamedArgs);
}

public static void UpdateArg(DispParams dp, Variant v, int i)
{
int ri = dp.cArgs - 1 - i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private int[] GetDispIDs(string propName)

var dispIds = new int[names.Length];
var hr = dispatch!.GetIDsOfNames(
emptyGuid,
in emptyGuid,
names,
(uint)names.Length,
LOCALE_USER_DEFAULT,
Expand All @@ -126,9 +126,9 @@ private int[] GetDispIDs(string propName)

var hr = dispatch!.Invoke(
dispIds[0],
emptyGuid,
in emptyGuid,
LOCALE_USER_DEFAULT,
kind,
(ushort)kind,
dispParams,
variantResult.Ptr,
0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal partial interface IDispatch

[PreserveSig]
int GetIDsOfNames(
Guid riid,
in Guid riid,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] rgszNames,
uint cNames,
uint lcid,
Expand All @@ -29,9 +29,9 @@ int GetIDsOfNames(
[PreserveSig]
int Invoke(
int dispIdMember,
Guid riid,
in Guid riid,
uint lcid,
INVOKEKIND wFlags,
ushort wFlags,
[MarshalUsing(typeof(DispParamsMarshaller))] in DispParams pDispParams,
nint pVarResult,
nint pExcepInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal partial interface IRibbonControl : IDispatch
int get_Id([MarshalAs(UnmanagedType.BStr)] out string result);

[PreserveSig]
int get_Context(nint result);
int get_Context(out nint result);

[PreserveSig]
int get_Tag([MarshalAs(UnmanagedType.BStr)] out string result);
Expand Down
Loading