|
ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-08-2022 01:36 |
|
I'm using an old CD version in a 32bit Access VBA application. Looking to possibly move this to a 64bit Access database, but I'm running into trouble with Chart Director.
I'm currently using this code for getting the API into VBA:
Set ACTCTX = CreateObject("Microsoft.Windows.ActCtx")
ACTCTX.manifest = CurrentProject.Path & "ChartDirectorcd.config"
Set CD = ACTCTX.CreateObject("ChartDirector.API")
The final line there is failing with the error:
"Automation error %1 is not a valid Win32 application."
Is there something that I need to do differently to load this, or some change to my manifest file that needs to happen? Or will this just not work in a 64-bit environment? |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-09-2022 03:21 |
|
Hi Andrew,
If your ChartDirector for ASP/COM/VB is released after Jun 2009, the ChartDirector.API should work in both 32-bit and 64-bit environment.
Due to the nature of COM and ActiveX technology, all components, including ChartDirector, needs to be registered with the operating system. If you install ChartDirector for ASP/COM/VB using the downloaded installer, it should automatically register ChartDirector for both 32-bit and 64-bit applications. In some cases, you may need to run the installer using "Run As Administrator" (eg. if your own account does not have sufficient privilege to register software).
If you manually register ChartDirector, make sure you launch the command shell using "Run As Administrator", and then use the "regdll" included in ChartDirector/lib to register ChartDirector. If you use "regsvr32" to registered ChartDirector, it will only register it for 32-bit usage. The "regdll" will register it for both 32-bit and 64-bit usage. See the "Installing ChartDirector without Using the Installer" for more details:
https://www.advsofteng.com/doc/cdcom.htm#install.htm
For the manifest file, it should not be necessary if you register ChartDirector using the above method.
Regards
Peter Kwan |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-10-2022 20:41 |
|
I've got 5.1.1 from 2012, so I guess the version should be fine. I need to use the manifest technique, though, for my application.
Here's my code (this is working on 32bit):
Set ACTCTX = CreateObject("Microsoft.Windows.ActCtx")
ACTCTX.manifest = CurrentProject.Path & "ChartDirectorcd.config"
Set CD = ACTCTX.CreateObject("ChartDirector.API")
On 64-bit, this is throwing an error on the "Set CD" line:
"Automation error %1 is not a valid Win32 application."
Is there something that I need to change in the CD.config file (attached)?
|
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-11-2022 14:13 |
|
Hi Andrew,
I have just tried to see if it is possible to use "Reg-free COM" for ChartDirector in 64-bit mode. In my testing, it works after adding the proxyStubClsid32 attribute the the assemblyIdentity. See the attached cd.config file.
To use the ChartDirector API, we need to declare some functions "CreateActCtxW" and "ActivateActCtx" in VBA. The declarations in 64-bit is different from 32-bit. (For example, in many places, the "Long" data type has to be changed to "LongPtr".) The followings are the code that I used to load the ChartDirector.API object.
Private Declare PtrSafe Function CreateActCtxW Lib "kernel32" (ByVal ACTCTXData As LongPtr) As LongPtr
Private Declare PtrSafe Function ActivateActCtx Lib "kernel32" (ByVal hActCtx As LongPtr, ByVal lpCookie As LongPtr) As LongPtr
Private Type ACTCTX
cbSize As Long
dwFlags As Long
lpSource As LongPtr
wProcessorArchitecture As Integer
wLangId As Integer
lpAssemblyDirectory As LongPtr
lpResourceName As LongPtr
lpApplicationName As LongPtr
End Type
Private Function loadCD() As Object
'
' cdSave is declared in a VBA Module as "Public cdSave As Object"
'
If cdSave Is Nothing Then
Dim p As String
p = ThisWorkbook.Path
Dim m As String
m = p & "cd.config"
Dim x As ACTCTX
x.cbSize = 28
x.lpSource = StrPtr(m)
x.lpAssemblyDirectory = StrPtr(p)
Dim h As LongPtr
Dim n As Long
h = CreateActCtxW(VarPtr(x))
Set cdSave = CreateObject("ChartDirector.API")
End If
Set loadCD = cdSave
End Function
From our previous communications many years ago, I think you do not use the ChartViewer.ocx control (because GUI controls would not work with reg-free). With the proxyStudClsid32, the BaseChart.makePicture method also would not work, as it returns an "OLE Picture object" that cannot be handled with the "proxy stub". It you need to obtain a Picture object to be displayed in the GUI, you can use something like:
' Create chart as a temporary image file
Dim fName
fName = Environ("temp") & "test.bmp"
Call c.makeChart(fName)
' Display the temporary image file
Set x = Me.OLEObjects("Image1").Object
x.Picture = LoadPicture(fName)
Hope this can help.
Regards
Peter Kwan
|
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-11-2022 20:35 |
|
Thanks for the reply - I don't see the proxyStubClsid32 attribute in your cd.config file, though. Yours looks identical to mine, except the assemblyIdentity version number is lower in yours.
For these charts, I'm using makeTmpFile to create a png and then just viewing that from the application. Would that function still work? |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-11-2022 21:04 |
|
Hi Andrew,
Sorry, I attached the wrong cd.config. The correct one is attached with this message.
Yes, you can use PNG/JPG/BMP/SVG/PDF as well. You can choose the format that can be viewed by your application. I use BMP in my test code because it is fastest.
PNG has a smaller file size than BMP because it compresses the image. It is useful if the image is to be transferred via the network or permanently stored in the disk. If the image file is temporary and the image is viewed on the same machine, BMP can be faster because it does not have compression, and the viewer does not need to decompress the image to view it.
Regards
Peter Kwan
|
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-12-2022 03:33 |
|
I'm not having much success yet - when I use the other cd.config file, with my code I get an error about the "side-by-side configuration" being incorrect. It tells me to check the event log, and when I do that, I see it's saying:
"The attribute proxyStubClsid32 is not permitted in this context on element assemblyIdentity." |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-12-2022 19:04 |
|
Hi Andrew,
Sorry for this problem. I did my test on an old Windows 7 machine and Office 2010. (This is the only 64-bit office we have. All our other MS offices are 32-bit.) After some more testing on Windows 10, I found that it does not work. I came to the conclusion that for COM, we must register the ChartDirector DLLs before they can be used on 64-bit Windows.
I am thinking, if you do not want your user to have an additional installation step (which is just to run a batch file to register the DLLs), may be in you can registered the DLL in VBA by "shell out" to the command prompt and run a batch file before using ChartDirector. The registration step would then hidden from the user.
It is possible to registered COM components without requiring admin rights, in which case the registration is for that user only instead of machine wide. However, Microsoft does not provide the command line tool to do this. (The Microsoft regsvr32 tool registers machine wide and requires admin rights.) We need a third party executable regsvrex to do this. This executable is open source and compiled to 7K bytes only. It is under the 'The Code Project Open License" which to my understand means it can be distributed free of charge. See:
https://github.com/vadz/RegSvrEx
If the above method is OK for you, I can try it to make it work.
Regards
Peter Kwan |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-12-2022 20:37 |
|
That could be an option for me - assuming that can run without admin rights. |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-14-2022 03:21 |
|
Hi Andrew,
I have just uploaded the files to register the ChartDirector for ASP/COM/VB on 64-bit Windows without requiring administrative privileges. In this case, the registration is only for the user who do the registration.
https://www.advsofteng.com/support/cdreg64.zip
Some Windows machines may block or prevent any downloaded executable files from running (even if they are included in zip files). To avoid uncertainties, please unblock the downloaded files. See:
https://www.advsofteng.com/unblock_zip.html
There are 5 files inside. The cdreg.bat and cdunreg.bat are for registering and unregistering the ChartDirector for ASP/COM/VB. The ChartDirector DLLs (comchartdir.dll, aspapi.dll and chartdir??.dll.) must be copied to the same directory as the batch files in order to register them.
The "regsvrex.exe" is a utility used by the batch files. It is a third party open source item. You would need to agree to the licensing conditions of the original author. As far as I know, it is free to use and distribute in closed source commercial products. The link to the license is near the bottom of the following page:
https://www.codeproject.com/Articles/3505/RegSvrEx-An-Enchanced-COM-Server-Registration-Util
In your VBA code, you can "shell out" to execute the cdreg.bat to registered ChartDirector before using it. Note that in many VBA environment, the "Shell" command is asynchronous, that is, it will return without waiting for the batch file to finish. If you execute the "Shell" command and then immediately create the ChartDirector.API object, it may fail because the registration has not been completed yet. You can consider to use the "Run" method of the "WScript.Shell" object, which allows you to wait until the batch file has been completed. ("WScript.Shell" is a Microsoft object available in all Windows computer.)
To avoid uncertainties, when executing the batch file, please use the full path name. You may use VBA to obtain the path that contains your application to determine the full path name of the batch file. It is quite common for Windows to set the default directory to the directory of the executable (that is, msaccess.exe if you are using MS Access), and not the directory of your database or project file.
Regards
Peter Kwan |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-14-2022 03:32 |
|
Thanks for this - I'll try to have a crack at it soon. If I need to stick with 32bit, though, I may just do that. |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-20-2022 01:49 |
|
I'm starting to dive into this now - I've got all of my other windows API calls working properly in 64 and 32bit, and now just have ChartDirector left.
I tried a few other things to get the manifest method working, but had no luck.
I noticed that the cdreg.bat file still raised a UAC prompt, so I switched the last line to use "reg import cd.reg" instead of regedit. You'd technically want to edit cdunreg.bat as well. That way there's no UAC prompt at all. It does seem to work ok, as far as registering it goes. Now I've just got to see about modifying my existing code. So far so good, though. |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Andrew on Jan-20-2022 04:26 |
|
That didn't take long - I got it working! Thanks so much for the help!! |
Re: ChartDirector VBA Reg-free COM method for 64-bit |
Posted by Peter Kwan on Jan-20-2022 15:10 |
|
Hi Andrew,
Thanks a lot for your feedback. I will change the "regedit" line to "reg import cd.reg" in the cdreg and cdunref batch file.
Regards
Peter Kwan |
|