-
[RESOLVED] Externally compiling / unregistering VB-created DLL
Think dilettante will chime. I somewhat remember a project where he did something similar but can't remember where I saw it...
Completely in uncharted waters here. I've never compiled a VB application via a command line and am looking for some pointers. To make this a bit easier to offer advice, it is a very specific scenario. Here's a reference from msdn, but not exactly sure what to use or which are mandatory, optional or preferred? Are those the only switches I need to be concerned with? This is where the gurus' experiences can help me.
I want to create a DLL project through code, drop it in a subfolder and compile it and then immediately unregister the DLL. This is nothing nefarious. I'm looking at an option to automate creation of resource-only DLLs. Ideally this would have no user interaction other than specifying the DLL's name and which resources to include. Assuming the coder has admin rights, no other interaction should be needed I think. I'm assuming (bad idea, huh?) that since VB will be used to kick off the command-line compilation, if the coder has admin rights to begin with, shouldn't be any hassles there. Correct?
This is something else I'd like some advice on: automating the unregistering, especially with regards to 32 and 64 bit systems if a Shell command is recommended. If an API will do this -- great!
-
Re: Externally compiling / unregistering VB-created DLL
Aside from the issue that VB6.exe is a Windows Subsystem program. That has implications for things like a run via an non-interactive service context.
Otherwise just be sure the .VBP file has all of the paths defined, in particular for the output DLL.
As far as unregistering goes you can do a LoadLibrary on the DLL, grab and execute its self-unregistration entrypoint. See Self-Registration.
-
Re: Externally compiling / unregistering VB-created DLL
-
Re: Externally compiling / unregistering VB-created DLL
To both of you, thanx for the tips.
@dilettante, the implications you are describing would result in what? I'm not sure what you mean -- I'm a newbie in this arena.
-
Re: Externally compiling / unregistering VB-created DLL
Most people never bump into a problem unless they do something like try to run a program on a server that's completely headless (special Windows builds).
But it can also fail for a non-interactive Service that tries to run it. One case that could be an issue would be Windows Scheduler with the use logged off, but I don't think that service is ever running truly non-interactive on a normal Windows build. Easy enough to try I suppose.
-
Re: Externally compiling / unregistering VB-created DLL
Thanx. Don't foresee this being an issue. The project would be used by VB coders as needed, likely while they are coding. This option I'm contemplating is fluff, but if gonna include it, want it to be automated.
-
Re: Externally compiling / unregistering VB-created DLL
I hesitated to bring it up, but figured somebody else would toss it out as a monkey wrench. People run into the problem once in a while when trying to do scripted builds as part of some source code management service.
In hindsight I shouldn't have said a word. Sorry to drag you off topic.
-
Re: Externally compiling / unregistering VB-created DLL
Quote:
Originally Posted by
dilettante
I hesitated to bring it up, but figured somebody else would toss it out as a monkey wrench. People run into the problem once in a while when trying to do scripted builds as part of some source code management service.
In hindsight I shouldn't have said a word. Sorry to drag you off topic.
no way - definitely good (on topic) info. Automated build systems are very relevant.
-
Re: Externally compiling / unregistering VB-created DLL
-
Re: Externally compiling / unregistering VB-created DLL
This might be stating the obvious, but I assume we're talking about ActiveX.dll files. Here's the way I deal with them:
Basically, when it's all said and done, once my ActiveX.dll is compiled, I throw it into my .RES file. Then, when I need it, I unpack it into a "Dependencies" subfolder, and then execute it with some code that The Trick helped me put together, which doesn't require any registration.
And here's what I do during development.
- Write the code for the ActiveX.dll.
- Compile it in the IDE. I suppose I could figure out how to compile it from the command line, as this is how I compile my main .EXE project.
- Delete the .EXP and .LIB files that were created along with the ActiveX.dll.
- Use the script below to unregister the ActiveX.dll (just dragging it onto the script).
- Put the ActiveX.dll in my .RES file.
- And then other mechanisms taking over from there (as suggested above), allowing me to run in an entirely "portable" way.
Again, I'm not sure if that helps anything or not, but that's how I do it.
The script I use for un-registering (I believe dilettante originally wrote this script, but I no longer remember for sure):
Code:
Option Explicit
Private Const ssfSYSTEMx86 = &H29
Private System, WinVer
If WScript.Arguments.Count < 1 Then
WScript.Echo "Missing DLL parameter." & vbNewLine _
& "Use DLLUnreg.vbs fullpathtoDLL" & vbNewLine _
& "or drag DLL's icon onto this script's icon."
Else
System = CreateObject("Shell.Application").NameSpace(ssfSYSTEMx86).Self.Path
With CreateObject("WScript.Shell")
WinVer = .RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
If Fix(CSng(WinVer)) < 6 then
'Win2K or XP (run by admin user).
.Run """" & System & "\regsvr32"" /u """ & WScript.Arguments(0) & """"
Else
'Vista or later, request elevation.
With CreateObject("Shell.Application")
.ShellExecute System & "\regsvr32", "/u """ & WScript.Arguments(0) & """", , "runas"
End With
End If
End With
End If
All the best,
Elroy
-
Re: Externally compiling / unregistering VB-created DLL
Elroy, not quite. This isn't some DLL that will be used as-is. It isn't even a DLL per-se -- no executable code at all.
A resource only DLL is simply a DLL with a resource file & nothing else. Consider it a portable res file that is not compiled into your application. It does not need to be registered, nor should it be. Unfortunately, VB auto-registers DLLs when they are compiled on source PC which results in need to unregister. This isn't truly needed for deployment, but why keep 'dead' information in the registry if you can avoid it. The unregistering is simply to clean up afterwards.
@dz32. I was thinking along your lines too, regarding the stub. Just didn't want to deal with potential malware/antivirus warnings potential.
-
Re: Externally compiling / unregistering VB-created DLL
Another thing to add - If it's a resource only DLL, why use VB at all?
A strictly resource only DLL doesn't have anything to register.
edit: Lavolpe beat me to it...
-
Re: Externally compiling / unregistering VB-created DLL
Hmmm, interesting idea, an external resource file. I assume you've got some minimal code in the DLL for actually extracting the resources. Or are you using a "resource hacker" approach?
If you're using the "resource hacker" approach, why not just distribute the actual RES file, and not deal with the complications of going through a DLL? Hacking (and extracting files from) a RES file is a bit different from doing the same to a DLL, but certainly doable, and a layer less of complexity. It'd also circumvent any concerns over registering/unregistering.
Also, just as a thought, it can't be that difficult to extract files from a RES files, as that's exactly how the VB6-IDE does it when you're executing code from the IDE. That's something I do all the time and that works flawlessly.
Best,
Elroy
-
Re: Externally compiling / unregistering VB-created DLL
There's no code in a resource only dll... (/NOENTRY)
And you specify a module with the the resource APIs.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
-
Re: Externally compiling / unregistering VB-created DLL
Couple good questions there Elroy
1. The easiest way to access these resource-only DLLs (which are a Windows standard implementation by the way) are via resource APIs, i.e., FindResource and LoadResource (for any resource type) or APIs like LoadString, LoadBitmap, LoadIcon, LoadImage, etc for specific resource types. The code required is actually not very long, just a few lines in a well-designed custom function.
Edited: resource-only DLL accessed from your project via code something like this
Use LoadLibrary, if not already done, to map the DLL into your app's process
-- remove when no longer needed, via FreeLibrary
Use FindResource/LoadResource to extract resource item bytes or use specific APIs like LoadString, etc
That's it, just can't use VB's LoadRes[xxxx] functions
2. Reason why you don't distribute/extract the res file as-is, without compiling into DLL, is so that it is compatible with APIs else one needs their own parsing routines to extract the data. Some APIs (LoadImage for example) have features that could be desirable when loading from a resource.
-
Re: Externally compiling / unregistering VB-created DLL
The easiest method of creating resource-only DLLs appears to be using VB6's Link.exe directly. The only source files you need is the res file itself. Example:
Link.exe /DLL /NOENTRY /MACHINE:IX86 /SUBSYSTEM:WINDOWS,4.0 "path/file of resfile" /OUT:"path/filename of new dll"
Only catch is that CVTRES.exe is required. That res file conversion tool likely exists on the PC somewhere. If not, one can find it easily enough to download. It is a Microsoft app that converts res files into COFF format. Advantage: no registering/unregistering of activex dll, no vbp/cls file.
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
If I recall correctly CVTRES.exe is spawned by a Link.exe run, not explicitly beforehand by you.
Or am I mis-remembering?
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
Probably mis-remembering sort of. CVTRES isn't even part of VB6 installation as far as I know. If you call Link.exe without CVTRES in the %PATH%, then you'll get an error stating Link couldn't execute CVTRES.
VB creates the COFF format as its OBJ files. The res file, when VB6 is used, is compiled into the COFF OBJ. So, CVTRES isn't needed. However, if you are not going to create a project that would do that, and just using the res file as the only object sent to Link.exe, then CVTRES is required.
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
I guess what I was trying to say is that to do what you suggest your "build" process does not have to include a step that manually runs CVTRES because LINK will do it.
VB6 doesn't need it because VB6.EXE Make does the CVTRES operation itself.
So LINK needs to be able to find CVTRES, but only when fed a .RES file.
CVTRES would be part of the VC6 toolchain and install with VC6, but it might also be found elsewhere on the VS6 or MSDN Library CDs.
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
Correct, all points.
We have at least 2 ways to create a compiled resource-only DLL
1) Create an activeX DLL with the res file, compile it (thru VB or shelling VB6), unregister the DLL (if clean-up is desired)
2) Get a copy of CVTRES.exe, place it in the VB6 folder, and run Link.exe from a command prompt (or Shell'ed)
Another option which I am not interested in would be to create the COFF ourselves. But then one would have to be 100% fluent in how the res file is actually converted to COFF.
At this point, fluff being the word I chose for this option, not sure how I want to proceed or whether I will proceed with that option. May just be a 'help/info only' item.
Edited: vbAdvance (written by Peter Young) had a resource-only DLL option. Guess what it farmed the workload too? CVTRES.exe
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
Quote:
Originally Posted by
LaVolpe
Edited: vbAdvance (written by Peter Young) had a resource-only DLL option. Guess what it farmed the workload too? CVTRES.exe
Good to know, considering it's one of the few add-ins I keep loaded.
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
Just FYI for anyone that comes to this thread...
A final solution for this specific scenario ended up using VB6, all done dynamically, JIT:
1. Create a vbp (DLL vs EXE) & cls file (no code), both relatively generic
2. Ensure the vbp file includes the resource file reference & class reference, no other refs needed, i.e., stdOle
3. Include the [VBCompiler] section in the vbp file
4. Shell & wait for for "vb6.exe /m "path/file to that tmp vbp file"
5. Use LoadLibrary, GetProcAddress & DispCallFunc API to call that new DLL's DllUnregisterServer function. Use FreeLibrary to release
6. Clean up excess files generated by VB: .lib and .exp and also the tmp vbp & cls files
Edited: The sample provided by Eduardo in post #3 is similar to what I'll use in step 5 above. However, I opted against CallWindowProc in that example. It's pushing 16 extra bytes on the stack that will never be cleaned up. Do this enough times, might have some issues.
Code:
[VBCompiler]
Linkswitches = /DLL /NOENTRY /MACHINE:IX86 /SUBSYSTEM:WINDOWS,4.0
If CVTRES exists, it can be used instead and creates a true standard DLL vs ActiveX (unregistered). However, I have had problems in some cases using LoadLibrary to access the created DLL's resources. I'll need to look into that & it may be a CVTRES version issue (newer one). If I'm going to shell out anyway, I decided to opt for VB6 over CVTRES. More steps involved, but not having any problems accessing the DLL created by VB. In my case, the tool that will offer this is designed to be used by VB coders.
-
Re: [RESOLVED] Externally compiling / unregistering VB-created DLL
Why not just use an existing template of an (unregistered) Ax-Dll - storing it inside your "Resource-App".
I've just compiled an empty minimum Ax-Dll-Project to PCode...
And it came out as a 16kB-binary...
After zipping it - I got 2KB...
Base64-encoding it, 2.6KB...
And that resulting 2.6KB Base64-string could be placed in 2 or 3 lines as a String-Const in your VB-Code
(usable from there as a template, whenever you want to open up a new "plain resource Dll").
In case you want to make this template-Blob even smaller, then just produce an empty one with TinyCC or FreeBasic.
Olaf