Flexcel need gdiplus ressources or others for PDF?

Hi,

I have an old project using BC6 (can not move it to XE2) so for that I make a dll exposing some methods of Flexcell api.

On my developer post all is working well (Windows 7 x32) but when I send to the client on windows Server 2008 is not working any more.

The problem come from "ExportAllVisibleSheets" which is throwing an external exception !

The code is :

	TFlexCelPdfExport* viPdf = NULL;
	viPdf             = new TFlexCelPdfExport(_Xls);
	TFileStream* viFs = new TFileStream(pFile, fmCreate);
	try {
		viPdf->BeginExport(viFs);
		viPdf->PageLayout = TPageLayout::Outlines;
		piLog("peFile_SaveToPdf : export en cours...");
		viPdf->ExportAllVisibleSheets(false,TPath::GetFileNameWithoutExtension(pFile));
		viPdf->EndExport();
	}
	__finally {
		viFs->Free();
		viPdf->Free();
	}


I have read in forums about gpiplus problem in DLL, so I have tried to init gpiplus in main program , but it does not help :
// Before using DLL
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// And after no more using the DLL
Gdiplus::GdiplusShutdown(gdiplusToken);

For information without gpiplus initialized it crash immediately, when initialized it crash after 20/30s.

So the problems seem's to come from GDIPlus.
Unfortunately I can not debug software on client side.

Hi,

The strange thing is that it works in the development machine, if it was a gdiplus initialization issue (which might be) it shouldn't work there either.
Can you try by doing:

1)Wrap the code above into a try/catch block, and log the exception message somewhere, so we can have an idea of what the error is.

The methods in the dll should catch all the exceptions anyway, since those won't propagate to the calling app. There should be some error code and message set in the dll, so the BCB app can check if the call went ok.

2)Check if you are initializing GDIPlus in the main thread, not inside another thread. GdiPlus must be initialized from the main thread only, and this is why we can't do it when you are running in a dll.


  1. It just return : "Exception extern", nothing more :(
    2) I am well in main thread (it's a CGI) because I have only one.

"The strange thing is that it works in the development machine, if it was a gdiplus initialization issue (which might be) it shouldn't work there either." 

I agree, so it's why I was thinking you are using external components (dll) which are surely not the same on my two machine.

We also use AdvApi32.dll and Crypt32.dll to read and write encrypted files (which despite their names are both available in win32 and win64), but that shouldn't really matter, since those are standard in any windows installation.


Just to be sure this isn't related to some corrupt/wrong dll, what happens if you create a console app in XE2, and write the same code as in the dll?  Does it work when it is in a standalone exe, or does it fail too?

I would expect that it will work when compiled as an exe, but I'd like to be sure we aren't searching for the wrong problem. As while it is true that you need to initialize GDIplus when in a dll, it isn't normally problematic, you just initialize it and it works. So maybe there is something unrelated going on.

Same problem with console application.


#pragma hdrstop
#pragma argsused


#include <tchar.h>
#include <stdio.h>


#include <vcl.h>


#include <VCL.FlexCel.Core.hpp>
#include <FlexCel.XlsAdapter.hpp>
#include <FlexCel.Pdf.hpp>
#include <FlexCel.Render.hpp>




int _tmain(int argc, _TCHAR* argv[]) {


	char* pFile = "test.xls";


	TXlsFile* _Xls = new TXlsFile(true);
	_Xls->Open(pFile);


	TFlexCelPdfExport* viPdf = NULL;


	viPdf             = new TFlexCelPdfExport(_Xls);
	TFileStream* viFs = new TFileStream("test.pdf", fmCreate);


	viPdf->BeginExport(viFs);
	viPdf->PageLayout = TPageLayout::Outlines;
	viPdf->ExportAllVisibleSheets(false, "TEST");


	viPdf->EndExport();


	 viFs->Free();
	 viPdf->Free();
	 _Xls->Free();


	return 0;
}

Have tried to put the two dll (AdvApi32.dll and Crypt32.dll) from my W7 to folder where is the console application (in WS2008), but problem still here.

Have tried also on another computer with WS2008, same problem.

Have you checked if your component is working on Windows Server 2008 (x32) ?

I've tested it with 2012, but there is some time since I don't try WS2008. I'll setup a VM and try it.

Note : the problem is depending of the content of the xls file (with images included).

Can you give me an email (or ftp, ...) to send you my excel file (confidential file - 473Ko)

Yes, please send me the file to adrian@tmssoftware.com   

We'll treat it as confidential and remove it once we are finished testing it.

I've further retested the console app in WS2012 and it seems to be working fine, I am waiting for a clean VM install of VS2008 to finish, but I don't expect it will give issues with my test file. So if I can get the file with actual issues, it might help a lot.

Regards,
   Adrian.

Hi,

Thanks, I got the file, and I tested the c++ app you posted in both WS2008 R2 (freshly installed, "standard" setup) and 2012, but I couldn't see any errors. In both the pdf file was created correctly.

Some things to try:
1)I'd like to see if this is related to GDI+ or to the PDF engine. So can you try the following:





#pragma hdrstop
#pragma argsused


#include <tchar.h>
#include <stdio.h>


#include <vcl.h>


#include <VCL.FlexCel.Core.hpp>
#include <FlexCel.XlsAdapter.hpp>
#include <FlexCel.Pdf.hpp>
#include <FlexCel.Render.hpp>




int _tmain(int argc, _TCHAR* argv[]) {


	char* pFile = "test.xls";


	TXlsFile* _Xls = new TXlsFile(true);
	_Xls->Open(pFile);


	TFlexCelImgExport* viImg = NULL;


	viImg             = new TFlexCelImgExport(_Xls, true);


	viImg->SaveAsImage("test.png", TImageExportType::Png, TImageColorDepth::TrueColorAlpha);


	 viImg->Free();
	 _Xls->Free();


	return 0;
}




If this works, then it isn't GDI+ related.

2)If 1) worked, then the next would be to see if this isn't related to the fonts (which are the most problematic issue when running pdf exports in a server, FlexCel needs to find and parse the ttf files).

Try with this code:



#pragma hdrstop
#pragma argsused


#include <tchar.h>
#include <stdio.h>


#include <vcl.h>


#include <VCL.FlexCel.Core.hpp>
#include <FlexCel.XlsAdapter.hpp>
#include <FlexCel.Pdf.hpp>
#include <FlexCel.Render.hpp>




int _tmain(int argc, _TCHAR* argv[]) {


	char* pFile = "test.xls";


	TXlsFile* _Xls = new TXlsFile(true);
	_Xls->Open(pFile);


	TFlexCelPdfExport* viPdf = NULL;


	viPdf             = new TFlexCelPdfExport(_Xls);
	TFileStream* viFs = new TFileStream("test.pdf", fmCreate);


	viPdf->BeginExport(viFs);
	viPdf->PageLayout = TPageLayout::Outlines;
	viPdf->FontMapping = TFontMapping::ReplaceAllFonts;
	viPdf->ExportAllVisibleSheets(false, "TEST");


	viPdf->EndExport();


	 viFs->Free();
	 viPdf->Free();
	 _Xls->Free();


	return 0;
}


The fontmapping line will make FlexCel replace all the fonts by internal pdf fonts, so we can see if this is font related or not.

Solution (1) is working only if first sheet is "Bon de commande", if I change sheet order then is not working anymore.

What are the sheets that don't work?  Is it sheet3?  (which has a very big bitmap)


Also, are you still getting an external exception, or do you get any other message?

Just to make sure we are speaking about the same, if you try with code like this: (note I set active sheet to 3, I assume that one is the one with problems)





#pragma hdrstop
#pragma argsused


#include <tchar.h>
#include <stdio.h>


#include <vcl.h>


#include <VCL.FlexCel.Core.hpp>
#include <FlexCel.XlsAdapter.hpp>
#include <FlexCel.Pdf.hpp>
#include <FlexCel.Render.hpp>




int _tmain(int argc, _TCHAR* argv[]) {


try
{
	char* pFile = "test.xls";


	TXlsFile* _Xls = new TXlsFile(true);
	_Xls->Open(pFile);


	TFlexCelImgExport* viImg = NULL;


	viImg             = new TFlexCelImgExport(_Xls, false);


	_Xls->ActiveSheet = 3;
	viImg->SaveAsImage("test.png", TImageExportType::Png, TImageColorDepth::TrueColorAlpha);


	 viImg->Free();
	 _Xls->Free();
}
catch (Exception &ex)
{
	wprintf(ex.Message.w_str());
}


	return 0;
}


Do you see an external exception? A dialog box telling that the app stopped working?

Sheet 2 and 3 don't work.

For message I don't know, I cannot check (can not debug on WS2008 client side)
I have only this :
Signature du problème :
  Nom d’événement de problème:	APPCRASH
  Nom de l’application:	Project1_png.exe
  Version de l’application:	0.0.0.0
  Horodatage de l'application:	00000000
  Nom du module par défaut:	rtl160.bpl
  Version du module par défaut:	16.0.4504.48759
  Horodateur du module par défaut:	4fa07358
  Code de l’exception:	c0000005
  Décalage de l’exception:	0000c5a2
  Version du système:	6.0.6002.2.2.0.400.8
  Identificateur de paramètres régionaux:	1036
  Information supplémentaire n° 1:	03af
  Information supplémentaire n° 2:	8396fee4acafded33de0d392b63f54ec
  Information supplémentaire n° 3:	4f4b
  Information supplémentaire n° 4:	bb17f27a87d29ec476f4628783d68895

If exporting to png isn't working, then indeed it looks like a GDI+ error.

1)Can you copy the newest gdiplus.dll in your development machine to the folder where you deploy the console app so it uses that one instead?

2)If 1) fixes the error (let's hope so) can you try maybe to install this update in the servers?:
http://support.microsoft.com/kb/958911 
I've tried it here with WS2008 R2, and from what I see in that page, this hotfix applies to WS2008 but no WS2008 R2, maybe it is related.

Can send me your "gdiplus.dll" by email : ochoteau@cedricom.com.

http://support.microsoft.com/kb/958911 doesn'y install : can't apply on my system (it should be for WS2008 with SP2).

Can send me your "gdiplus.dll" by email : ochoteau@cedricom.com.

http://support.microsoft.com/kb/958911 doesn't install : can't apply on my system (it should be for WS2008 withOUT SP2).

I have installed last from MS but does not help :(

SDK GDI+ : http://www.microsoft.com/en-us/download/details.aspx?id=18909