forked from florentbr/SeleniumBasic
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gen-registration.ipy
100 lines (83 loc) · 4.09 KB
/
gen-registration.ipy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""Script to create the registration file for innosetup.
Usage: ipy gen-registration.ipy c:\\assembly.dll c:\\outfile.pas
"""
import os, sys, re, argparse, subprocess, tempfile
import clr, System
from System.Reflection import Assembly, AssemblyDescriptionAttribute
from System.Runtime.InteropServices import GuidAttribute, TypeLibVersionAttribute \
, ComVisibleAttribute, InterfaceTypeAttribute, ProgIdAttribute
PROXYSTUBS = [
'{00020424-0000-0000-C000-000000000046}', #DUAL: PSOAInterface
'{00020424-0000-0000-C000-000000000046}', #IUnknown: PSOAInterface
'{00020420-0000-0000-C000-000000000046}' #IDispatch: PSDispatch
]
def main(args):
in_dll = os.path.abspath(args[0])
out_file = os.path.abspath(args[1])
if not os.path.isfile(in_dll):
raise Exception('Assembly not found: "%s"' % in_dll)
print "Assembly : .\%s" % os.path.relpath(in_dll, os.getcwd())
print "OutFile : .\%s" % os.path.relpath(out_file, os.getcwd())
print ""
print 'Parse the .Net assembly ...'
assembly = Assembly.LoadFile(in_dll)
assembly_fullname = assembly.FullName
assembly_filename = os.path.basename(in_dll)
ass_guid = GetAttribute(assembly, GuidAttribute)
ass_vers = GetAttribute(assembly, TypeLibVersionAttribute)
ass_desc = GetAttribute(assembly, AssemblyDescriptionAttribute)
lines_classes = []
lines_interfaces = []
lines_values = []
types = assembly.GetExportedTypes()
for type in types:
comvisible = GetAttribute(type, ComVisibleAttribute, silent = True)
if comvisible and comvisible.Value == True:
att_guid = GetAttribute(type, GuidAttribute)
guid = '{' + att_guid.Value + '}'
if type.IsClass:
hasConstructor = type.GetConstructor(System.Type.EmptyTypes) is not None
if hasConstructor:
progid = GetAttribute(type, ProgIdAttribute).Value
lines_classes.Add("RegClass(lib, '%s', '%s', '%s');" % (guid, progid, type.FullName))
elif type.IsValueType:
lines_values.Add("RegRecord(lib, '%s', '%s');" % (guid, type.FullName))
elif type.IsInterface:
interfaceType = GetAttribute(type, InterfaceTypeAttribute).Value
proxystub = PROXYSTUBS[int(interfaceType)]
lines_interfaces.Add("RegInterface(lib, '%s', '%s', '%s');" % (guid, type.Name, proxystub))
print 'Genereate the registration file ...'
with open(out_file, 'w') as f :
f.write("{\n")
f.write(" Code generated at each build by gen-registration.ipy\n")
f.write(" This is a subset of SeleniumBasicSetup.iss\n")
f.write("}\n\n")
f.write("lib.Guid := '{%s}';\n" % ass_guid.Value)
f.write("lib.FullName := '%s';\n" % assembly_fullname)
f.write("lib.Description := '%s';\n" % ass_desc.Description)
f.write("lib.TypeVersion := '%s.%s';\n" % (ass_vers.MajorVersion, ass_vers.MinorVersion))
f.write("lib.PathDll := ExpandConstant('{app}\%s');\n" % assembly_filename)
f.write("lib.PathTlb32 := ExpandConstant('{app}\%s');\n" % re.sub('\.[^.]+$', '32.tlb', assembly_filename))
f.write("lib.PathTlb64 := ExpandConstant('{app}\%s');\n" % re.sub('\.[^.]+$', '64.tlb', assembly_filename))
f.write("lib.Runtime := '%s';\n" % assembly.ImageRuntimeVersion)
f.write("\n")
f.write("RegTypeLib(lib);\n")
for lines in [lines_classes, lines_interfaces, lines_values]:
f.write('\n')
lines.sort()
for line in lines:
f.write(line + '\n')
print "\nDone"
def GetAttribute(obj, att_typename, silent = False):
type = clr.GetClrType(att_typename)
attributes = obj.GetCustomAttributes(type, False)
if attributes.Length == 0 :
if not silent:
raise Exception("Attribute {0} is missing on type {1}".format(type.Name, obj.FullName))
return None
return attributes[0]
if __name__ == '__main__':
if len(sys.argv) == 3 :
main(sys.argv[1:])
else:
print __doc__