IIRC, the typlibinfo object is not meant to be run in compiled apps,
since typelibs are compiled into the exe. This is why tlb's are not
required to be shipped as part of an installation.
I guess not. I just tried On Error Resume Next - but this does not change anything.
The mentioned line of code should be pretty fundamental for the serializing process - so there shouldn't be any error at all...
Is this on Vista?
I am developing on XP SP3, but tested it also on 7: same effect there (I did run it as admin)! (on Vista it should be the same like on 7)
Does this occur when making calls to/from the registry?
No, there are no registry calls at all.
The code uses Microsoft XML, v2.6 and TypeLib Information components to retrieve all class members. It returns the class properties as XML string, which is stored to disk afterwards (in AppData folder).
Please check the code on the linked page (link on the bottom) to see what I mean.
In IDE everyhing works perfectly, but after compilation it is the opposite:
Reading the XML file does not work, but there also no crashes/errors occuring.
Trying to write the XML file does send my app to nirvana...
IIRC, the typlibinfo object is not meant to be run in compiled apps, since typelibs are compiled into the exe. This is why tlb's are not required to be shipped as part of an installation.
Ok, this makes sense.- But how can I get the code working as compiled exe?
IIRC, the typlibinfo object is not meant to be run in compiled apps,
since typelibs are compiled into the exe. This is why tlb's are not
required to be shipped as part of an installation.
TlbInf32 is a DLL, not a TLB, and can run in a compiled exe. A COM DLL(or OCX) has a type library stored in it. TlbInf32.Dll wraps API oleaut32.LoadTypeLib() which lets you load Com object and returns the ITypeLib interface.
Many thanks dilettante, your demo gave me the key!
I did not compile my classes to a dll - if this is done, it works also on my system as executable.
I guess, I have to move my classes out now...
(My example should not be needed any more now.)
But I have got another question now:
Is it possible to serialize arrays and object this way also?
Code:
' If tMem.ReturnType.VarType = VT_DISPATCH Then
' '.. do nothing or do it recursive
' ElseIf tMem.ReturnType.VarType = VT_ARRAY Then
' '.. do nothing or do it somehow else
' End If
I think this comment is pointing out, that this is doable - do you have an idea, how to fulfill this task also?
The first If there is checking for a Property that is an object I think. So as suggested, you'd need to have the routine call itself recursively to handle THAT object's properties too. This would require more work though, since you'd want the sub-object inserted into the parent object's XML.
The second If is detecting an array of course. This would also require some more work, first deciding how you want an array to be represented in your XML, then writing the code required to create those XML nodes and populate/extract each array element.
While the example Function works, it is pretty ragged and primitive. You should probably rewrite the whole thing as a Class. Instead of one Function you could then have several routines bundled together. I suggest this because you'll probably find you have code you want to reuse, like the code you'll need for handling each property can be reuse when processing an array - which will also need to process objects in the array.
There is another approach that is more in the spirit of VB6 and it doesn't need the TlbInf32.dll either. Plus it should work for internal private Classes as well as public (registered COM DLL) classes:
Hello dilettante, thank you for your reply. I guess I need your Help again.
Originally Posted by dilettante
The first If there is checking for a Property that is an object I think. So as suggested, you'd need to have the routine call itself recursively to handle THAT object's properties too. This would require more work though, since you'd want the sub-object inserted into the parent object's XML.
The second If is detecting an array of course. This would also require some more work, first deciding how you want an array to be represented in your XML, then writing the code required to create those XML nodes and populate/extract each array element.
Ok, that was acutally pretty clear to me too - but not how to solve this in detail...
I did spend some nights on that topic now and it seems, that I did run into some problems!
I could do this for the object handling - please see the attached project. (btw: objects (class instances) acutally have the VarType VT_VARIANT).
But I have problems with arrays: Since VB does not allow public arrays in classes, one must use Let and Get properties to make private arrays public. Getting the array works also, but how can I Let it back?
There would also be the possibility to use a parameterized property to return the array. But in this case my serializer cannot retrieve the array bounds.
The only thing I can do is, to assume that a property with one parameter is an array. Then trying to use zero as the first parameter. If this fails, trying it with 1 and than looping until an error occurs. But then the class is limited to array indexes starting at 0 or 1.
I would like to implement both features, so that my lib is as much flexible as possible.
Originally Posted by dilettante
While the example Function works, it is pretty ragged and primitive. You should probably rewrite the whole thing as a Class. Instead of one Function you could then have several routines bundled together. I suggest this because you'll probably find you have code you want to reuse, like the code you'll need for handling each property can be reuse when processing an array - which will also need to process objects in the array.
Hmmm. I did split the function into serialize and deserialize for better readable code. For having objects as properties or objects in array properties, I can call my functions recursively. Why do I need a class for this?
Originally Posted by dilettante
There is another approach that is more in the spirit of VB6 and it doesn't need the TlbInf32.dll either. Plus it should work for internal private Classes as well as public (registered COM DLL) classes:
This should be familiar to anyone who has used VB6's native binary PropertyBag objects for persistence.
Yes, I did use PropertyBag objects for UserControls, but I don't like them actually, because they need a lot of extra code...
The reason for my serializer was to save an applications settings configuration. I thought, the best would be to instantiate a class, which holds all the parameters and saving that object to disk. Doing this binary would cause problems, if parameters are added in newer versions of the application. - At least users will lose their configuration in this case.
So I came up with the idea to serialize the object. The intension is to have an universal serializer, which can handle any kind of class WITHOUT writing extra code within the class (this is also the reason, why private properties are not an issue - there are no private properties in my case).
The property bag solution needs this and it would blow up the code by 200% (every property/parameter needs code for reading and writing). Instead of doing this, I could also write an ini file via an extra module and keep the classes itself clean.
I am wondering, why they do this in that way???
Why having an event for reading AND writing seperatly? - Wouldn't it half the work, if that is done just in one routine?
I did change the code that way and it works perfectly (please see the other folder in the attachment)