ellem has asked for the wisdom of the Perl Monks concerning the following question:

I need to Unregister and Register many, many DLLs. Directories of DLLs to "Fix" a problem with Crystal Reports 10. I can't find any module that is built for this and I am not asking for code.

My problem is I don't exactly know where to start. The W2K commandline regsrv32 only seems to work on one DLL at a time (that is regsvr32 *.dll doesn't work.) Which is probably safe and smart... Sadly I need neither of those at the moment. Seagate's (the makers of Crystal Reports) advice is basically, see which DLLs come up bad and manually register them. While that is fine advice it looks like about 125 or so DLLs need to be registered. And yes I'd love to not be using this product but it came bundled with a Third Party Vendor's software that my company HAS to use. I need to fix about 5 machines out of 120 which the TPV seems to think is "pretty good".

OK so here's how I see it. I read in the directory all the DLLs then create a commandline to Unregister all of the DLLs then Resgister all the DLLs I read in.

I would backtick ` the command (ie `regsvr32 -u crappycrystal.dll` ; Maybe print it out to a file to read later to see how it went. So there would be some loop.

Here's where things get fuzzy for me. I know how I would do a loop in the until ($foo=0) { way but I have no idea how to loop through all the DLLs. I don't how to tell it is done.

And because I have horrid self doubt I am pretty sure this is a stupid way to do this. So I ask you fellow Monks how would you handle this? And is there a wheel I don't need to reinvent?
ell em 52@g mail,com
There's more than one way to do it, but only some of them actually work.

20050114 Edit by castaway: Changed title from 'Resgistering DLLs, lots of them'

Replies are listed 'Best First'.
Re: Registering DLLs, lots of them
by BrowserUk (Pope) on Jan 13, 2005 at 01:57 UTC

    In the short term, this may get you started. In the long term, buy a good book :)

    #! perl -slw use strict; open 'LOG', '>', 'rereg.log' or die $!; while( glob '*.dll' ) { print LOG "unregister $_:", `regsvr32 -U $_`; print LOG "Register $_ :", `regsvr32 $_`; } close LOG;

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      BrowserUK has given you a good solution. To add on use system instead of back ticks ``. Get the system commands out put and determine whether it was success or not.

      eg:$result=system("regsvr32 -U $_");
      Now determine the $result value and find out the result.


        I concur.

        I just discovered that regsvr32 doesn't provide any useful output--chosing to display errors in a popup instead.

        So the OP should also include /s to disable that.

        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.
Re: Resgistering DLLs, lots of them
by Tanktalus (Canon) on Jan 13, 2005 at 02:13 UTC

    The first note from Thor is incomplete - @ARGV is not auto-globbed on any platform, although unix shells automatically expand wildcards. You'd have to do something like:

    foreach my $dll (map { glob $_ } @ARGV) { register($dll); }
    to get it to work on Windows. I'm making a wild assumption you don't care about Linux or Unix ;-). Then you'd call your script like perl rereg.pl *.dll.

    The next part is what you want to do with it. There may be a way to find out if a DLL is already registered properly - whether you use the Win32::* functions/modules, or if regsvr32 has a query mode. Then you can skip that DLL and go on to the next. Ideally you'd use the Win32::* functions/modules, but you could use regsvr32 querying, if it exists, as a quick fix for the short term. Or you could blindly call regsvr32 on each DLL - I would recommend logging the $? from doing so, though - it's incredibly useful information which may cause you to figure out a way later to detect when a second registration has failed, and reattempt registering it immediately (left as an excersise for a future PM question ;->).

    As for "I'm pretty sure this is a pretty stupid way of doing this" - I'm unconvinced. Stupid problem, maybe. Stupid solution, no.

Re: Resgistering DLLs, lots of them
by gellyfish (Monsignor) on Jan 13, 2005 at 09:18 UTC

    Nothing to do with Perl but something that I find very useful are these registry settings:

    REGEDIT4 [HKEY_CLASSES_ROOT\.dll] @="dllfile" [HKEY_CLASSES_ROOT\dllfile\shell\Register Component\command] @="regsvr32 \"%1\"" [HKEY_CLASSES_ROOT\dllfile\shell\Unregister Component\command] @="regsvr32 /u \"%1\"" [HKEY_CLASSES_ROOT\.exe] @="exefile" [HKEY_CLASSES_ROOT\exefile\shell\Register Component\command] @="\"%1\" /regserver" [HKEY_CLASSES_ROOT\exefile\shell\Unregister Component\command] @="\"%1\" /unregserver" [HKEY_CLASSES_ROOT\exefile\shell\Register As Service\command] @="\"%1\" /service" [HKEY_CLASSES_ROOT\.ocx] @="ocxfile" [HKEY_CLASSES_ROOT\ocxfile\shell\Register Component\command] @="regsvr32 \"%1\"" [HKEY_CLASSES_ROOT\ocxfile\shell\Unregister Component\command] @="regsvr32 /u \"%1\""
    You should just save that in to a file with a .reg extension and then double click on it to load it into the registry. THis will get a 'Register Component' and 'Unregister Component' entries in the right click context menu - this means that you can select multiple .dlls (or .exes or .ocxs or whatever) and right click to select the appropriate action and they will all be done at once - the only drawaback is the annoying popups you get for each one but hey!


Re: Registering DLLs, lots of them
by thor (Priest) on Jan 13, 2005 at 01:53 UTC
    What about
    foreach my $dll (@ARGV) { print "$dll\n"; }
    Place this in a file called dllfix.pl or something. Then, from the commandline, you can call "dllfix.pl *.dll", and it should print out all of the dlls. My code only prints the dll name, but you can easily modify it to perform whatever operation on $dll that you want. I leave that as an exercise to the reader.


    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come