VahidN / EPPlus.Core

EPPlus.Core is an unofficial port of the EPPlus library to .NET Core
GNU Lesser General Public License v3.0
370 stars 93 forks source link

Decrypt using password error #34

Closed JasonFoglia closed 6 years ago

JasonFoglia commented 6 years ago

Unable to read encrypted excel files, using DotNet Core 2 and MacOS.

Exception has occurred: CLR/System.Runtime.InteropServices.MarshalDirectiveException An exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in EPPlus.Core.dll but was not handled in user code: 'Cannot marshal 'parameter #3': Unknown error.' at OfficeOpenXml.Utils.CompoundDocument.CreateILockBytesOnHGlobal(IntPtr hGlobal, Boolean fDeleteOnRelease, ILockBytes& ppLkbyt) at OfficeOpenXml.Utils.CompoundDocument.Read(Byte[] doc) at OfficeOpenXml.Encryption.EncryptedPackageHandler.DecryptPackage(FileInfo fi, ExcelEncryption encryption) at OfficeOpenXml.ExcelPackage.ConstructNewFile(String password) at ExcelInputHelper.ToHashtable(String excelPath, Boolean returnJustHeader, String password) in /Users/jasonfoglia/Desktop/Eligibility/Helpers/ExcelInputHelper.cs:line 16 at Eligibility.Controllers.EligibilityController.InputFields(String inputFile, String password) in /Users/jasonfoglia/Desktop/Eligibility/Controllers/EligibilityController.cs:line 32 at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext()

VahidN commented 6 years ago

Can you run this test?

            string file = Path.Combine("bin", "issue34.xlsx");
            const string password = "EPPlus";
            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("Employee");

                worksheet.Cells[1, 1].Value = "ID";
                worksheet.Cells[1, 2].Value = "Name";
                worksheet.Cells[1, 3].Value = "Gender";
                worksheet.Cells[1, 4].Value = "Salary (in $)";

                worksheet.Cells[2, 1].Value = 1000;
                worksheet.Cells[2, 2].Value = "Jon";
                worksheet.Cells[2, 3].Value = "M";
                worksheet.Cells[2, 4].Value = 3000;

                package.SaveAs(new FileInfo(file), password);  //default encryption (AES128)
            }

            using (var package = new ExcelPackage(new FileInfo(file), password))
            {
                var worksheet = package.Workbook.Worksheets[1];
                Console.WriteLine(worksheet.Cells[2, 1].Value);
                //Assert.AreEqual("1000", worksheet.Cells[2, 1].Value.ToString());
            }
VahidN commented 6 years ago

True. CreateILockBytesOnHGlobal uses ole32.dll

        [DllImport("ole32.dll")]
        static extern int CreateILockBytesOnHGlobal(
            IntPtr hGlobal,
            bool fDeleteOnRelease,
            out ILockBytes ppLkbyt);

which is not available on other operating systems.

JasonFoglia commented 6 years ago

Other then this issue with protected excel files, it works great on Mac.

Thank you for your time working on this.