DLLREGISTERSERVER, DLLUNREGISTERSERVER in VB
- Heroyin
VB as a language that makes it easy to play, allowing developers to quickly start, fast development, high efficiency. But it is over-packaged also brings many inconvenience to developers.
Origin of the problem
I have encountered a trouble in I have developed a plug-in structure. My project is used in the COM architecture. The framework is developed by Delphi, the plugin is COM component, and the plugin can be developed by other languages, and of course, VB. Each plugin must be registered as a fixed component category (categories). It is very simple to implement in other languages such as VC, Delphi, just overloading DLLREGISTERSERVER, DllunRegisterServer adds a registration logout class code in two functions, and then output it. But it has been troublesome to VB.
VB is normal to develop standard DLLs directly, so it does not support custom export functions. When developing Active DLLs, it is automatically exported by VB DllgetClassObject, DllcanunloadNow, DllRegisterServer, DllunregisterServer. To join the registration logout category, you must re-export DllRegisterServer, DllunregisterServer.
Ok, the problem is converted into how to guide the function in the VB written DLL.
VB compilation insider
The compilation process of VB is approximately as follows. When we write the code in the editing environment, the VB call C2 compiles all modules (including Class) to an OBJ file (the code that can be identified for the machine language). It is some compilation parameters for C2 (E):
- The the name of the prefixed one Used for the names of the rowscontaining 'precompilato, One
RISEN OF INTERMEDIATE TAILS (from Which Name of The Switch) Temport; The Rows Are 5 and Finish Withi Suffissi GL, SY, FORMER, IN AND DB; THEY Contained Are Not Document
- f the name of the rows to compile
- W3 Warning Level 3, Level of 'Attenzione' Dedicating to I Warnings
- GY IT Qualifies The Connection To Level of Function (Function-Level Linking)
- G5 Optimization for the Pentium
- GS4096 IT Allows NOT To INSERT The Code for the Control of Stack (Stack Probe) IF A Function Does Not
Use more Than 4096 byte of stack
DOS Not Document
- Z1 It Removes The name of the bookcase of default from the rows.obj
- FOFILEOBJ THE Name of Rows Obj To Generate (Rows Output) - Qifdiv It Putput - Qifdiv It Puts in Action The Corrections for the Bug of The Division of The Pentium (fdiv bug)
- Mililiter IT Creates Rows Eseguibile Single-Threaded
- Basic It Indicates The Compiler C2 The Fact That The Compilation IT Happens for a Plan Basic
C2 After completing compilation, VB will call Link.exe to connect all OBJ files into an EXE file to complete the compilation process. Here is a command line demonstrate how to call Link.exe:
Link c: /test/modulo1.obj c: /test/progetto1.obj C: / Programmi / Microsoft Visual Studio / VB98 / VBAEXE6.LIB / Entry: __ VBAS / OUT: C: / Test / progetto1.exe / base: windows, 4.0 /version: 1.0 / debug / debugtype: CV / Incremental: not /opt:ref/merge: 4078
There is no significance of these parameters for us, and it will be used by default. This command line does not include an output function. If we want to output a function, you can define a .def file, add the list of functions you want to output by format, and then add "/ Def: file name" after the command line (of course also You can directly add / exports parameters), then call the command line to compile, use the Denpendency tool to view you will find the function you want to output.
Def file format definition:
LIBRARY program name
Description "MyDLL - (c) Antonio Giuliana, 2004"
Exports
Function name =? Function name @ function The module name @@ aagxxz
...
example:
Library mydll
Description "MyDLL - (c) Antonio Giuliana, 2004"
Exports
DllRegisterServer =? DLLREGISTERSERVER @ symexp @@ aagxxz
DllunRegisterServer =? DllunregisterServer @ symexp @@ aagxxz
Note: The function name and module name are case sensitive.
After finding the solution, however, since the VB compiles are complete, the OBJ file is automatically deleted, how can C2 generation After the OBJ file is generated after the compilation process gets the OBJ file, there is a way to replace the LINK file of the VB, and then interrupt Let's copy the OBJ file and compile it with the command line. This is a good way, but it is not intelligent, I found a more effective way to abroad.
Auxiliary compilation tool for making VB
Create a new project, named LINK, join the code during the main process:
Public SUB
Main
()
DIM CMD AS STRING
DIM Fout As Long
Dim Sout As String
Dim Sdef as string
CMD = Command $ IF INSTR (cmd, "/ dll")> 0 and INSTR (cmd, "vbaexe6.lib"> 0 THEN
Fout = INSTR (cmd, "/ out:")
Sout = MID (CMD, Fout 6, INSTR (CMD, "/ BASE:") - Fout - 8)
SDEF = LEFT (Sout, Len (Sout) - 3) "DEF"
IF LEN (Dir (SDEF)) THEN
CMD = CMD & "/ Def:" "" & SDEF & "" ""
END IF
END IF
Shell "Link32.exe" & cmd
End Sub
Then compile to link.exe, first change the link.exe under the VB directory to link32.exe, then copy the link.exe to the VB directory, the benefit of doing the original compilation process, just compiling the DLL It is only inserted into the "/ def:" parameter and does not affect compilation other programs.
After completing the replacement, if you want to output other functions, you can only need to edit the suffix ".def" file with the output file in the program output directory.
Start replace DLLREGISTERSERVER, DLLUNREGISTERSERVER
1. Making a registration and logging of toolbase companies in Comregisterdll
New project, introduce two libraries: ISA Helper Comssent 1.0 Type Library and TypeLib Information. Create a class COMREGISTER, implement a method in the COMREGISTER class:
Regtypelib (Slib As String, Byval Bstate As Boolean, Byval BthreadModel as EthreadModel) is used to implement registration and logout ActiveX. code show as below:
Option expedition
Public Enum EthreadModel TMapartment = 0 & '"Apartment" TMSINGLE = 1 &' "Single" End Enum
Private Type Guid Data1 As Long Data2 AS Integer Data3 AS Integer Data4 (0 to 7) AS Byteend Type
PRIVATE ENUM ESYSKIND SYS_WIN16 = 0 & SYS_WIN32 = 1 & Sys_MAC = 2 & End Enum
Private Declare Function LoadTypeLib Lib "oleaut32.dll" (_ pFileName As Byte, pptlib As Object) As LongPrivate Declare Function RegisterTypeLib Lib "oleaut32.dll" (_ ByVal ptlib As Object, szFullPath As Byte, _ szHelpFile As Byte) As LongPrivate Declare Function UnRegisterTypeLib Lib "oleaut32.dll" (_ libID As GUID, ByVal wVerMajor As Integer, _ ByVal wVerMinor As Integer, ByVal lCID As Long, _ ByVal tSysKind As eSYSKIND) As LongPrivate Declare Function CLSIDFromString Lib "ole32.dll" (lpsz As Byte, pclsid As GUID) As LongPrivate Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As LongPrivate Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal LPModulenAme As String) AS Longprivate Declare Function MessageBox Lib "User32" Alias "Messageboxa" (Byval Hwnd As String, Byval Lpcaption As String, Byval Wtype As long) AS LO NgPrivate Function Message (estr as string) MessageBox 0, estr, "", 0nd function
Private Function GetModulePath (bModuleName As String) As StringDim ModleId As LongDim Path As String * 254 ModleId = GetModuleHandle (bModuleName) Call GetModuleFileName (ModleId, Path, 254) GetModulePath = PathEnd Function
Private function setKeyandValue (byval szkey as string, _ byval szsubkey as string, byval szvalue as string) as booleandim cr AS new cregistry cr.classkey = hkey_classes_root cr.sectionKey = SZKEY
Cr.createKey cr.valuekey = szsubkey cr.valueType = reg_sz cr.value = szvalue
END FUNCTION
Private Function RegisterServer (ByVal clsid As String, _ ByVal szFileName As String, ByVal szProgID As String, _ ByVal szDescription As String, ByVal szVerIndProgID As String) As LongDim szKey As String szKey = "CLSID /" clsid "/" SetKeyAndValue szKey , "" ", SZDescription " InprocServer32 / "," ", SZFileName
IF (SZProgid <> ") THENSEYANDVALUE SZKEY " Progid / "," ", SZProgid SetKeyandValue Szprogid " / CLSID / ",", ", CLSID END IF
IF (SzverindProgid <> ") THEN 'Add The Version-Independent Progid Subkey Under Clsid Key " VersionIndependentProgid "," ", SzverindProgID
'Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT. SetKeyAndValue szVerIndProgID, "", szDescription SetKeyAndValue szVerIndProgID "/ CLSID /", "", clsid SetKeyAndValue szVerIndProgID "CurVer /", "", szProgID
'Add the versioned progid subkey under hkey_classes_root. SetKeyandValue Szprogid, "" ", SZDescription SetKeyandValue Szprogid " / CLSID / ",", ",", ""
END FUNCTION
Private Function DeleteAllKey Dim (bClassKey As ERegistryClassConstants, bParentKey As String, bSubKey As String) As BooleanDim cR As New cRegistry cR.ClassKey = bClassKey cR.SectionKey = bParentKey "/" bSubKey Dim hKey () As String Dim hCount As Long I As Long Dim returnResult As Boolean cR.EnumerateSections hKey, hCount For I = 1 To hCount If Not DeleteAllKey (bClassKey, bParentKey "/" bSubKey, hKey (I)) Then DeleteAllKey = False Exit Function End If Next cR.SectionKey = BParentKey Cr.ValueKey = BSUBKEYDELETEALLKEY = cr.deleteKey () end function
Private function unregister (Byval SzProgid As String, _ Byval SzverindProgid As String)
DeleteallKey HKEY_CLASSES_ROOT, "CLSID", CLSID END FUNCTION
Public Function RegTypelib (sLib As String, ByVal bState As Boolean, _ bClassName As String, _ ByVal bThreadModel As eThreadModel) As Long Dim suLib () As ByteDim errOK As LongDim bClassGuid As String Dim cTLI As TypeLibInfoDim iMajor As Integer, iMinor As IntegerDim DllPath As String DllPath = GetModulePath (sLib) Set cTLI = TLI.TypeLibInfoFromFile (DllPath) bClassGuid = cTLI.CoClasses.NamedItem (bClassName) .GUID iMajor = cTLI.CoClasses.NamedItem (bClassName) .MajorVersion iMinor = cTLI.CoClasses.NamedItem (bClassName ) .MinorVersion Set TypeReg2 = TypeReg If bState Then Dim szKey As String szKey = "CLSID /" bClassGuid "/" SetKeyAndValue szKey, "", sLib "." bClassName SetKeyAndValue szKey "InprocServer32 /", "", Dllpath Select Case BthreadModel Case TMAPARTMENT SETKEYANDVALUE SZKEY "InprocServer32 /", "ThreadingModel", "Apartment" Case TMSINGLE setKeyan dValue szKey "InprocServer32 /", "ThreadingModel", "Single" End Select SetKeyAndValue szKey "VersionIndependentProgID /", "", sLib "." bClassName SetKeyAndValue szKey "ProgID /", "", sLib ". " BClassName SetKeyandValue Slib ". " BClassName " / CLSID / ",", BCLASSGUID SetKeyandValue Szkey "Version /", "", Imajor & "& iMinor SetKeyandValue Szkey " Typelib / "
"" "" "" "" "" " This library is a public library, all of which require re-custom DLLREGISTERSERVER, DLLunregisterServer can be easily referenced to easily complete registration and logout processes.
2, custom DLLREGISTERSERVER, DLLUNREGISTERSERVER
Create a new project MyDLL, introduce Comregiterdll.dll, add a Module MAINMODULE, and build two functions in MainModule DllregisterServer, DllunregisterServer:
Declare function messagebox lib "user32" alias "messageboxa" (Byval Hwnd as stay, byval lpcaption as string, byval WTYPE As long) As long
Public Function DllRegisterServer () As long
DIM Comreg As ComregIster
SET Comreg = New Comregister
'Join your processing code
MessageBox 0, "Registration Process", "MyDLL", 0
DllregisterServer = Comreg.RegTypelib ("MyDLL", TRUE, TMAPARTMENT)
END FUNCTION
Public Function Dllunregister () as long
DIM Comreg As ComregIster
SET Comreg = New Comregister
'Join your processing code
MessageBox 0, "Logout Process", "MYDLL", 0
DllunregisterServer = Comreg.RegTypelib ("MyDLL", FALSE, TMAPARTMENT)
END FUNCTION
Create a new MyDLL.DEF in the program directory, the DEF file content is as follows:
Library mydll
Description "MyDLL - (c) Antonio Giuliana, 2004"
Exports
DllRegisterServer =? DLLREGISTERSERVER @ mainmodule @@ aagxxz
DllunregisterServer =? DllunregisterServer @ mainmodule @@ aagxxz
Save, compile, run the regsvr32 Register MYDLL you discover the pop-up dialog "Registration Process"
Conclude
I use the export function to lead: http://www.visual-basic.it/uploads/articoli/tecnici/agdllbyvb.htm
I have encountered some problems in the process of implementation, which is to use a lot of methods during the export process, which may be due to VB's global object is not initialized, so encapsulate the registration method into ComregisterDll.dll. Go to the reference, if you don't rely on ComregisterDll.dll, you will be able to get the comregister to the unit of DLL to register, you will be wrong, you are welcome to discuss this problem with me. Also: I have no personal space that is not convenient to upload the source code. If you need it, you can contact him:
E-mail: Heroyin888@hotmail.com
QQ: 7878906