Custom DllRegisterServer and DllUnregisterServer in VB

Source: Internet
Author: User
Tags command line join visual studio
Server VB custom DllRegisterServer, DllUnregisterServer

-A ghost (Heroyin)

VB, as a simple and easy to use language, can let developers quickly start, development speed, high efficiency. But its excessive encapsulation also causes many inconvenience to the developer.

The origin of the problem
Recently I was in the development of a plug-in structure of the project encountered a problem, my project is the use of COM architecture, the framework by Delphi Development, Plug-ins for COM components, plug-ins can be developed by other languages, of course, including VB. Each plug-in must be registered as a fixed component category (Categories). In other languages such as VC, Delphi to achieve a very simple, only need to overload DllRegisterServer, DllUnregisterServer in two functions to join the Register unregister class code, and then output it. But to VB has encountered trouble.

VB under normal circumstances is not directly developed standard DLL, so also do not support custom export functions, the development of active DLLs, is automatically exported by VB four functions DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer. To join the registration logoff class code, you must re-export DllRegisterServer, DllUnregisterServer.

Well, the question is converted into how to export functions in VB-written DLLs.

VB compiling insider
VB compile process is roughly as follows, when we write code in the editing environment, VB call C2 all modules (including class) compiled into obj file (can be recognized for machine language code). It's C2. Some compilation parameter descriptions (e):

-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) temporary; These are rows are 5 and finish Withi Suffissi GL, SY, FORMER, in and DB; They contained are not documented

-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" control of stack (stack probe) If a function does not

Use more than 4096 byte of stack

-DOS not documented

-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 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 this compilation it happens for a plan basic



C2 finished compiling, VB will call LINK.EXE all obj files connected to exe file, complete the compilation process. Here is a command line that shows how to invoke LINK.EXE:

LINK C:\Test\Form1.obj C:\Test\Modulo1.obj C:\Test\Progetto1.obj C:\Programmi\Microsoft Visual studio\vb98\ vbaexe6.lib/entry:__ vbas/out:c:\test\progetto1.exe/base:0x400000/subsystem:windows, 4.0/version:1.0/debug/ Debugtype:cv/incremental:not/opt:ref/merge:.rdata =.text/ignore:4078
For us, these parameters have no meaning, the default is the line. The output function is not included in this command line. If we want to output a function, you can define a. DEF file, add a list of functions to output in the format, and then add "/def: FileName" (or, of course, direct addition/exports parameters) to the command line, and then invoke the command line compilation. Using the Denpendency tool to view you will find the function you want to output.

Definition of DEF file format:



Library program Name

DESCRIPTION "Mydll-(C) Antonio Giuliana, 2004"

Exports

function name =? functions name @ Function contains the module name @ @AAGXXZ

...

Cases:

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



Found the solution, however, since the VB compiled after the automatic deletion of obj file, how to C2 after the generation of obj file to interrupt the compilation process to obtain obj file, there is a way to replace the VB link file, and then interrupted, the obj file copied out, in the command line compiled. This is a very good way, but not smart enough, I found a more effective way on the foreign website.

Making VB Auxiliary compiling tool
Create a new project, named Link, and add code to 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 (sdef) Then
cmd = cmd & "/def:" "& Sdef &" "" "
End If
End If
Shell "LINK32. EXE "& cmd
End Sub
Then compiled into LINK.EXE, the first VB directory under the LINK.EXE renamed to LINK32.EXE, and then the LINK.EXE copy to the VB directory, the advantage is not to change the original compilation process, only when compiling the DLL to insert "/DEF:" Parameters, does not affect the compilation of other programs.

If you want to output other functions after the replacement operation is complete, simply edit a suffix with the same name as the output file in the program output directory. DEF "File on it.

Start replacing DllRegisterServer, DllUnregisterServer
1, the production of registration and cancellation of the tool library Comregisterdll

Create a new project that introduces two libraries: ISA Helper Com Component 1.0 Type library and TypeLib information. Create a class Comregister and implement a method in the Comregister class:

Regtypelib (Slib as String, ByVal bstate as Boolean) is used to implement registration and logoff ActiveX. The code is as follows:

Option Explicit

Public Type GUID

Data1 as Long

Data2 as Integer

Data3 as Integer

DATA4 (0 to 7) as Byte

End 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 Long

Private Declare Function registertypelib Lib "Oleaut32.dll" (_

ByVal Ptlib as Object, Szfullpath as Byte, _

Szhelpfile as Byte) as Long

Private 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 Long

Private Declare Function clsidfromstring Lib "Ole32.dll" (Lpsz as Byte, pCLSID as GUID) as Long

Private Declare Function getmodulefilename Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hmodule as Long, ByVal Lpfilen Ame as String, ByVal nsize as Long

Private Declare Function getmodulehandle Lib "kernel32" Alias "Getmodulehandlea" (ByVal Lpmodulename as String) as Long

' Get the path of the module

Private Function Getmodulepath (Bmodulename As String) as String

Dim Modleid as Long

Dim Path as String * 254



Modleid = GetModuleHandle (bmodulename)

Call GetModuleFileName (Modleid, Path, 254)

Getmodulepath = Path

End Function



' Slib is a module name and is unregistered without the path and suffix bstate false, whereas

Public Function Regtypelib (slib as String, ByVal bstate as Boolean, ByVal btype as PSDK. Eplugincategory) as Long

Dim Sulib () as Byte

Dim Errok as Long

Dim tlb as Object



Dim Ctli as Typelibinfo

Dim Tguid as GUID, sCLSID as String

Dim imajor As Integer, Iminor as Integer

Dim LCID as Long

Dim DllPath as String



DllPath = Getmodulepath (slib)

If bstate Then

' Basic automatically translates strings to Unicode Byte arrays

' But doesn ' t null-terminate, so your must do it yourself



Sulib = DllPath & vbNullChar



' Pass ' of array



Errok = LoadTypeLib (sulib (0), TLB)



If Errok = 0 Then

Errok = RegisterTypeLib (tlb, Sulib (0), 0)



End If

Regtypelib = Errok

Else



Set Ctli = TLI. Typelibinfofromfile (DllPath)

sCLSID = Ctli.guid

Imajor = Ctli.majorversion

Iminor = Ctli.minorversion

LCID = Ctli.lcid

Set Ctli = Nothing



Sulib = sCLSID & vbNullChar

Errok = clsidfromstring (sulib (0), Tguid)

If Errok = 0 Then





Errok = Unregistertypelib (Tguid, Imajor, Iminor, LCID, Sys_win32)

Regtypelib = Errok

End If



End If



End Function

Compile the project into ComRegiterDll.dll and register. This library is a common library, and all projects that need to be customized DllRegisterServer and DllUnregisterServer can easily be referenced to facilitate the registration and logoff process.



2, custom DllRegisterServer, DllUnregisterServer

Create a new project Mydll, introduce ComRegiterDll.dll, add a module mainmodule, create a new two function in Mainmodule DllRegisterServer, DllUnregisterServer:



Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd as Long, ByVal Lptext as String, ByVal lpcaption As String, ByVal wtype as long) as long

Public Function DllRegisterServer () as Long

Dim ComReg as Comregister

Set ComReg = New comregister

' Add in your processing code

MessageBox 0, "registration process", "Mydll", 0



DllRegisterServer = Comreg.regtypelib ("Mydll", True)

End Function



Public Function DllUnregisterServer () as Long

Dim ComReg as Comregister

Set ComReg = New comregister

' Add in your processing code

MessageBox 0, "logoff process", "Mydll", 0



DllUnregisterServer = Comreg.regtypelib ("Mydll", False)

End Function

The contents of a new Mydll.def,def file in the program directory are as follows:

LIBRARY Mydll

DESCRIPTION "Mydll-(C) Antonio Giuliana, 2004"

Exports

Dllregisterserver=? dllregisterserver@ Mainmodule @ @AAGXXZ

Dllunregisterserver=? dllunregisterserver@ Mainmodule @ @AAGXXZ

Save, compile, run regsvr32 register mydll you will find pop-up dialog "registration process"

Conclusion
I use the method of exporting a function quote: http://www.visual-basic.it/uploads/articoli/tecnici/agDllByVB.htm

I also encountered some problems in the implementation process, that is, in the process of exporting the function of many methods will have limitations, may be due to the VB of the global object uninitialized caused, So the registration method is encapsulated into the ComRegisterDll.dll, then to reference, if you do not rely on the ComRegisterDll.dll and directly put the Comregister into the DLL to register the unit to the reference will be wrong, you are welcome to join me to explore this problem solution.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.