- NSIS Discussion
- Better ActiveX registration
Archive: Better ActiveX registration
AsPhunck
26th August 2001 13:24 UTC
Better ActiveX registration
There's a problem with the way we can check the version number when doing ActiveX registration. It requires the filename on the install system...
Typically you want to install an ActiveX component if the file is newer than the one already on the system... The problem is that you don't know the filename/location of the component on the system. :( The only thing you know is the "class id" of the component that you want to install. And you dont want to write the class-id's in the NSIS script, instead you want the NSIS to retrieve it from the file in...
What I am looking for could be expressed in pseudo-code it as:
NDLL=the DLL in the NSIS package
IF NDLL.classid already exists on system {
SDLL=the install systems DLL coresponding to NDLL.classid
IF SDLL.version<NDLL.version {
UNREG SDLL
REG NDLL
}
}
I have no idea how to implement this in the NSIS source. But I doubt i am the only one that would like this feature. If there only was a function that could retrieve the filename of SDLL.
AsPhunck
29th August 2001 10:05 UTC
Am I the only one interrested in this?
I really can't imagine it.. If your product is one with lots of ActiveX components then this feature is almost essential.
This would be the case for almost all VB/Delphi coded products...
Anybody got a solution?
AsPhunck
29th August 2001 10:27 UTC
If nobody here has a solution then I think I will switch to the "inno" installer. It's also free, albeit not as cool...
I might even consider writing my own using the "Seer" Scripting language.
I don't want to switch so please send any solutions to my problem....
;)
pjw62
29th August 2001 16:24 UTC
oh no... an unbeliever.. arrhgg... I will see what I can do.. if you could find an expample of how to do this progmatically, I would appreciate. I cant give it a lot of attention at the moment 'cause I'm busy ;)
pjw62
29th August 2001 16:32 UTC
would one just read the reg key HKEY_CLASSES_ROOT\CLSID\<clsid goes here>\InprocServer32\
??
e.g.
the default key value for
HKEY_CLASSES_ROOT\CLSID\{00000107-0000-0010-8000-00AA006D2EA4}\InprocServer32 is "C:\PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\DAO\DAO360.DLL"
pjw62
29th August 2001 16:42 UTC
as well as that, there are various other keys that can be read to get filename of related modules (16/32 bit)..
(copied and pasted)
InprocHandler Registers a 16-bit handler DLL
@ String value
Specifies the custom handler used by the application.
InprocHandler32 Registers a 32-bit handler DLL
@ String value
Specifies the custom handler used by the application.
InprocServer Registers a 16-bit in-process server DLL
@ String value
Specifies the path to the in-process server DLL.
InprocServer32 Registers a 32-bit in-process server DLL
@ String value
Specifies the path to the 32-bit in-process server.
ThreadingModel String value
Specifies the threading model of the apartment the server can run in.
In-process servers are loaded into an existing apartment and so do not call CoInitialize or CoInitializeEx; they must use the registry to specify an application's threading model.
Allowable values are:
ThreadingModel=Apartment. Single-threaded apartment.
ThreadingModel=Both. Single-threaded or multithreaded apartment.
ThreadingModel=Free. Multithreaded apartment.
ThreadingModel=Neutral. Neutral apartment (available in Windows 2000).
Insertable Indicates whether the object is insertable in COM applications.
Objects of this class should appear in the Insert Object dialog box's list box when used by COM container applications.
@ String value
Specifies the path to the 32-bit in-process server.
LocalServer Full path to a 16-bit local server application
@ String value
Specifies the full path to the local server, and can include command-line arguments.
LocalServer32 Full path to a 32-bit local server application
@ String value
Specifies the full path to the local server, and can include command-line arguments.
pjw62
29th August 2001 20:24 UTC
"And you dont want to write the class-id's in the NSIS script, instead you want the NSIS to retrieve it from the file in... "
actually, on reading this, it seems that you also want a way to automatically get the CLSID from a program id, so you dont have to manually find the CLSID.
I haven't worked with COM/ActiveX objects before, but I think you need CLSIDFromProgID and StringFromCLSID.
I will implement this in the next release of my nsis dll.
I think it would be possible though, to load the CLSID directly from the CLSID registry key in HKEY_CLASSES_ROOT\<progid>. This would save a bit in your exe header.
AsPhunck
31st August 2001 20:54 UTC
Thanks a lot... this really helped me out :)
AsPhunck
31st August 2001 21:25 UTC
So How do you read the default value with ReadRegStr?
AsPhunck
1st September 2001 00:19 UTC
OK.....
Here's a little VBscript tool i made for genereating NSIS code for ActiveX registration.... :p
I have only tested it briefly so you might want to check it out yourself... I use the generated script in conjunction with the NSIS !include command. It seems to work great.
This is the ".vbs" CODE... If you want to know how it works i suggest you start reading about the TypeLibInfo object....
Option Explicit
Dim LabelOffset
Dim oFileOut
Dim oFSO
Dim oTLI
LabelOffset=1
Set oFSO=CreateObject("scripting.filesystemobject")
Set oFileOut = oFso.CreateTextFile("DLLs-include.NSI", True)
Set oTLI=CreateObject("TLI.TLIApplication")
dumpTypeLibInfo "c:\winnt\system32\msvbvm60.dll","$SysDir","c:\winnt\system32\vb6stkit.dll",true
dumpTypeLibInfo "c:\winnt\system32\comdlg32.ocx","$SysDir","",true
dumpTypeLibInfo "c:\winnt\system32\mci32.ocx","$SysDir","",true
dumpTypeLibInfo "c:\winnt\system32\mscomctl.ocx","$SysDir","",true
dumpTypeLibInfo "c:\winnt\system32\mswinsck.ocx","$SysDir","",true
dumpTypeLibInfo "c:\winnt\system32\tabctl32.ocx","$SysDir","",true
oFileOut.close
Sub dumpTypeLibInfo(localfilename,outpath,additionalfiles,isTypeLib)
Dim guid
Dim TII
Dim fname
Dim l
Dim sFiles
Set TII = oTLI.TypeLibInfoFromFile(localfilename)
fname = outpath & "\" & mid(localfilename,instrrev(localfilename,"\")+1)
guid = TII.GUID
oFileOut.WriteLine("SetOutPath """ & outpath & """")
If isTypeLib Then
oFileOut.WriteLine("ReadRegStr $9 HKCR ""TYPELIB\" & guid & "\" & TII.majorversion & "." & TII.minorversion & "\" & TII.lcid & "\win32"" """"")
Else
oFileOut.WriteLine("ReadRegStr $9 HKCR ""CLSID\" & guid & "\InprocServer32"" """"")
End If
oFileOut.WriteLine("ClearErrors")
oFileOut.WriteLine("StrCmp $9 """" RegisterDLL" & LabelOffset)
oFileOut.WriteLine("CompareDLLVersions /STOREFROM """ & localfilename & """ """ & fname & """ UnRegisterDLL" & LabelOffset & " RegComplete" & LabelOffset)
oFileOut.WriteLine("Goto RegComplete" & LabelOffset )
oFileOut.WriteLine("UnRegisterDLL" & LabelOffset & ":")
oFileOut.WriteLine("UnRegDLL """ & fname & """")
oFileOut.WriteLine("Sleep 1000")
oFileOut.WriteLine("RegisterDLL" & LabelOffset & ":")
oFileOut.WriteLine("File """ & localfilename & """")
sFiles=split(additionalfiles,";")
For l=0 to UBound(sFiles)
oFileOut.WriteLine("File """ & sFiles(l) & """")
Next
oFileOut.WriteLine("RegDLL """ & fname & """")
oFileOut.WriteLine("RegComplete" & LabelOffset & ":")
oFileOut.WriteLine("")
LabelOffset=LabelOffset+1
End sub
br0kenedge
3rd March 2003 20:20 UTC
I've been looking at safe ActiveX registration and came up with this script that seems to work well. Is there an easier way? If anyone has any suggestions or improvments feel free to post.
------------------
[edit]edited by kichik. please attach huge scripts. attached below :down:[/edit]
kichik
3rd March 2003 20:28 UTC
.
kichik
4th March 2003 17:02 UTC
Seems fine. You can put it in a function since it doesn't use the File command. You can also use the System plug-in to automatically get the GUID. Can you please add it to the archive so everyone else can easily find it?
br0kenedge
4th March 2003 23:05 UTC
>automatically get the GUID.
I originally thought I would do that. I figured I could write a DLL plugin to use "TLI.TLIApplication" to extract typeLibInfo. In order to do this though, I'd have to distribute (and register) TLBINF32.DLL which comes with Visual Studio.
> System plug-in
Does the System::call work on In-proc ActiveX components? (The documentation is hairy, it seemed like it was meant for standard DLLs)
Is there another way?
kichik
5th March 2003 15:18 UTC
I am sorry, I have no idea. I have never worked with ActiveX. Just thought you can call CLSIDFromProgID that pjw mentioned using System.dll but it doesn't seem like it accepts file names.
System.dll is meant for normal DLLs, but if the function is exported you can call it with System.dll. If they are not exported you'll have to use the same code you'll use with your C plug-in, but then again, it will be simpler to just create a plug-in.