The Code Cave

January 4, 2007

Trigger a hardware detection scan from Delphi, InstallShield, C++, script or Run prompt

Filed under: Batch, Delphi, RegEdit, WINDOWS, XP, installation — Brian @ 2:04 pm

In my deployment process, it had looked like I was going to need to detect some changes in hardware and then perform a reboot.
I researched how to do this but it turns ou that I don’t need this code. Into the cave it goes.

You can of course run the “Add New Hardware” wizard manually. Here’s the command line to do just that:
“C:\WINDOWS\system32\rundll32.exe” C:\WINDOWS\system32\shell32.dll,Control_RunDLL “C:\WINDOWS\system32\hdwwiz.cpl”,Detect Hardware

However, what if you want to automate the process.

The information for how to do this is relatively scarce even though there is a technet page about it. Strangely enough the first thing I found was an NSIS script for doing this through that open source instalation program. The strange thing about it is that it was on a WinAMP website (link).

Here’s that code:

CODE:
  1. Function ScanForNewHW
  2. SetPluginUnload alwaysoff
  3. StrCpy $1 “”
  4.  
  5. System::Call ’setupapi::CM_Locate_DevNodeA(*i .r0, t r1, i r2) i .r3′
  6. System::Call ’setupapi::CM_Reenumerate_DevNode(i r0, i r4) i .r5′
  7.  
  8. SetPluginUnload manual
  9. System::Free 0
  10. FunctionEnd

Armed with the DLL name, the second thing I found was an Install Shield script (link) that allowed it to be done:

CODE:
  1. function ScanForHardwareChanges()
  2.   NUMBER devInst, myreturn;
  3. begin
  4.   if(UseDLL(WINSYSDIR ^ “cfgmgr32.dll”) != 0)then
  5.     MessageBox(“Didn’t load Dll”, SEVERE);
  6.     return FALSE;
  7.   endif;
  8.   myreturn = CM_Locate_DevNodeA(&devInst, \0, 0);
  9.   myreturn = CM_Reenumerate_DevNode(devInst, 0);
  10.   UnUseDLL(WINSYSDIR ^ “cfgmgr32.dll”);
  11.   return TRUE;
  12. end;

Armed with the DLL name and a possible procedure name, I was able to track down the Microsoft support page about it (link). That page provided a C routine for calling the code. Here it is:

C:
  1. BOOL ScanForHardwareChanges()
  2. {
  3.     DEVINST     devInst;
  4.     CONFIGRET   status;
  5.    
  6.     //
  7.     // Get the root devnode.
  8.     //
  9.    
  10.     status = CM_Locate_DevNode(&devInst, NULL, CM_LOCATE_DEVNODE_NORMAL);
  11.    
  12.     if (status != CR_SUCCESS) {
  13.         printf(“CM_Locate_DevNode failed: %x\n, status);
  14.         return FALSE;
  15.  
  16.     }
  17.    
  18.     status = CM_Reenumerate_DevNode(devInst, 0);
  19.    
  20.     if (status != CR_SUCCESS) {
  21.         printf(“CM_Reenumerate_DevNode failed: %x\n, status));
  22.         return FALSE;
  23.     }
  24.  
  25.     return TRUE;
  26. }

However, I wanted to do this in Delphi. With the correct constant names, I was able to find two references to this routine. The Delphi JEDI project has a provides a routine for loading the DLL that allows these calls to be made and either someone (link) translated Microsoft’s code into a routine for scanning for the hardware or there was a, now gone, JEDI demo project that included this routine. Either way, the French site was the first one I’d found that scanned for new hardware with Delphi.

Here is that code:

DELPHI:
  1. procedure SomeProcedure;
  2.   // First you need to load the module. 
  3.   LoadConfigManagerApi; 
  4.   // Then call a translation of the MS routine
  5.   ScanForHardwareChanges;
  6. end;
  7.  
  8. //  Here’s the translation of the ScanForHardwareChanges
  9. function ScanForHardwareChanges: boolean;
  10. var
  11.   dev: DEVINST;
  12.   status: CONFIGRET;
  13. begin
  14.  
  15.   status := CM_Locate_DevNode(dev, , CM_LOCATE_DEVNODE_NORMAL);
  16.  
  17.   if (status <> CR_SUCCESS) then
  18.   begin
  19.     result := FALSE;
  20.     exit;
  21.   end;
  22.  
  23.   status := CM_Reenumerate_DevNode(dev, 0);
  24.  
  25.   if (status <> CR_SUCCESS) then
  26.   begin
  27.     result := FALSE;
  28.     exit;
  29.   end;
  30.   Result := TRUE;
  31. end;

That routine was picked up on a Russian site (link) and modified to be independent of the JEDI files. However, both of these routines include way more information than is needed.

The process is really simple.
1. Load the DLL
2. Get the location of the two methods you need.
3. Call them (using the appropriate constants
4. Unload everything.

I’ve written my own Delphi routine that does all that and has no extra baggage dragged (drug?) along for the ride..

My all-in-one solution:

DELPHI:
  1. {******************************************************************************
  2.   ScanForHardwareChanges
  3.   by Brian Layman at TheCodeCave.com
  4. ******************************************************************************}
  5. function ScanForHardwareChanges: Boolean;
  6. const
  7.   CFGMGR32_DLL                 = ‘cfgmgr32.dll’;
  8.   CM_LOCATE_DEVNODE_NAME       = ‘CM_Locate_DevNodeA’;
  9.   CM_REENUMERATE_DEVNODE_NAME  = ‘CM_Reenumerate_DevNode’;
  10.   CM_LOCATE_DEVNODE_NORMAL     = $00000000;
  11.   CR_SUCCESS                   = $00000000;
  12. var
  13.    DeviceNode: DWord;
  14.    HCfgMgr: THandle;
  15.    CM_Locate_DevNode: function(var dnDevInst: DWord; pDeviceID: PAnsiChar;
  16.                                ulFlags: ULONG): DWord; stdcall;
  17.    CM_Reenumerate_DevNode: function(dnDevInst: DWord; ulFlags: ULong): DWord; stdcall;
  18. begin // ScanForHardwareChanges
  19.   Result := FALSE;
  20.   HCfgMgr := LoadLibrary(CFGMGR32_DLL);
  21.   if (HCfgMgr <32)
  22.   then MessageDlg(‘Error: could not find Configuration Manager DLL’, mtError, [mbOk], 0)
  23.   else begin
  24.     try
  25.       CM_Locate_DevNode := GetProcAddress(HCfgMgr, CM_LOCATE_DEVNODE_NAME);
  26.       CM_Reenumerate_DevNode := GetProcAddress(HCfgMgr, CM_REENUMERATE_DEVNODE_NAME);
  27.       if (CM_Locate_DevNode(DeviceNode, NIL, CM_LOCATE_DEVNODE_NORMAL) = CR_SUCCESS)
  28.       then Result := (CM_Reenumerate_DevNode(DeviceNode, 0) = CR_SUCCESS);
  29.     finally // wrap up
  30.       FreeLibrary(HCfgMgr);
  31.     end;    // try/finally
  32.   end;
  33. end// ScanForHardwareChanges

As a bonus, here it is combined into a project that scans for new hardware and then reboots the computer.
(more…)

June 2, 2006

Copy To Clipboard in HTML

Filed under: Batch, HTML — Brian @ 12:47 am

or Speed blogging Exposed…
or “Copy as Text Link” and “Copy as Image Link” Blogging Tools explained.

Usually when I post something technical, I include a detailed rambling explaniation of how it does what it does. In the post “Copy as Text Link” and “Copy as Image Link” Blogging Tools” I created a batch file that did some neat stuff. But I didn’t give a full explaination of the details. Now I will.

The batch file did the following neat stuff…
1. Used Environmental variables to create HTML files in a standard Windows directory
2. Dynamically add string and DWord registry entries
3. Demonstrated adding menu items to Maxthon & Internet Explorer (Unfortunatly these do not show up in FF or Opera.)
4. Displayed different contexts based upon what was selected.
5. Launched another IE window that does not effect the output but does process information selected in the first.
6. Demonstrated how to copy HTML source to the paste buffer via HTML and javascript.:
7. Copied text to the clipboard, formatting it into HTML

Not bad for a small batch file.

So, here’s how the magic was done…

First, the easy stuff. The batch file creates two text files. That is done using the redirection symbol (aka the output to file symbol) which is > (aka the Greater Than sign). The Greater than sign appends the displayed results directly to a file. Two greater thans in a row cause the file to be recreated. I use the Echo command to echo (go figure) text to two HTML files I will be creating. Since I use >> in the first line, those files will always be recreated if the batch file is run again.

Because HTML also uses GT and LT symbols, they must be denoted as literal symbols. That is done with the carot symbol ^. Thusly

DOS:
  1. echo ^<HTML^>>%windir%\web\copytextaslink.htm
  2. echo ^<SCRIPT LANGUAGE="JavaScript" defer^>>>%windir%\web\copytextaslink.htm
  3. .

The result in the HTML file looks like this:

HTML:
  1. <SCRIPT LANGUAGE=“JavaScript” defer>

The batch actually creates two HTML files. One for handling Text that is selected. And another for handling an image being selected.

Let’s first look at the Text version. It is very short:

JavaScript:
  1. <HTML>
  2. <SCRIPT LANGUAGE=“JavaScript” defer>
  3. var parentwin = external.menuArguments;
  4. var doc = parentwin.document;
  5. var sel = doc.selection;
  6. var rng = sel.createRange();
  7. var str = new String(rng.text);
  8. window.clipboardData.setData(‘Text’, ‘&lt;a href="’ + parentwin.location + ‘">’ + str + ‘&lt;/a>’);
  9. </SCRIPT>
  10. </HTML>

As you can see, the bulk of the file is JavaScript. The second line clearly declares it so. However, instead of putting Language=”JavaScript” (which is the old school way of doing things and how I learned originally), I should have specified it as a MIME type like this Type=”text/javascript” The end result is the same, however eventually the old language option will be dropped.

Another option that you might not be familiar with is the defer flag. This is a browser load time optimizer. It tells the browser that the contents of the script will not effect the layout of the page and therefore the browser can continue drawing the page.

The process is also pretty easy to follow because it uses Microsoft’s DOM technology. DOM is the Document Object Module and allows IE to handle all web pages as if it were Object Oriented. You can reference the document and the various parts/divisions of any web page. And that allows you to directly access properties or methods of these objects.

So what the code above does is asks for the document in the parent window (the one in which you right clicked). It then asks for the current selection (if any). It then gets the current selection as text and then asks for the clibboard object for the current window. At that point it is a simple call to SetData and the selected text is added (with a few additions) to the clippboard. There isn’t much more than that. One thing that should be noted is that the type of data in the clibboard must be specified, in this case, as text. You can read more about the other types of data that a clib board can handle in my article about Clipboard manipulation with Delphi HERE:

The second file proceeds much the same way except that it goes further into the DOM and retreives the Height and Width of the original image so that the pasting of the tag in your blog can include that information (most specifically, the aspect ratio.

JavaScript:
  1. <HTML>
  2. <SCRIPT LANGUAGE=“JavaScript” defer>
  3. var parentwin = external.menuArguments;
  4. var doc = parentwin.document;
  5. var w;
  6. var h;
  7. var sel = doc.selection;
  8. var rng = sel.createRange();
  9. var str = new String(rng.text);
  10. if ( parentwin.event.srcElement.tagName == “IMG” )
  11. {
  12.     h = parentwin.event.srcElement.height;
  13.     w = parentwin.event.srcElement.width;
  14.     window.clipboardData.setData(‘Text’, ‘&lt;a href="’ + parentwin.location + ‘">&lt;img src="’ + parentwin.event.srcElement.href + ‘" Width = "’ + w + ‘" Height = "’ + h + ‘" alt="Click to go to the original site."/>&lt;/a>’);
  15. }
  16. else
  17.     alert (“Incompatible element. Select either just an image or just text.”);
  18. </SCRIPT>
  19. </HTML>

That’s it for the HTML. The only thing left is to create a couple of triggers to activate those two files. That’s done through the registry.

Internet explorer reads through the registry each time it pops up a menu. It first decides what is clicked and then looks at the registry entries under HKey_CurrentUser\Software\Microsoft\Internet Explorer\MenuExt\ all of the menu items that match the type of selection. MSDN has a full article that explains this in detail HERE, however, the following table is probably all you’ll need:

Context Value
Default 0×1
Images 0×2
Controls 0×4
Tables 0×8
Text selection 0×10
Anchor 0×20

So, the last step of the process is to route the text to the text processing HTML and the img tag source to the image text file.

That’s done in these two lines…

DOS:
  1. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Image as Lin&k" /ve /t REG_SZ /d "%WINDIR%\web\copyimageaslink.htm" /f
  2. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Image as Lin&k" /v Contexts /t REG_DWORD /d 2 /f
  3. .

That’s it! You’ve got your full walk through! Any questions?

May 26, 2006

“Copy as Text Link” and “Copy as Image Link” Blogging Tools

Filed under: Batch, HTML — Brian @ 7:10 pm

Justin of JustInsomnia had a great idea for a FireFox plug in:

I want to be able to copy a quote and its URL at the same time, without having to so much as think about it. To do so, I wrote my first Firefox extension, which I opted to name the somewhat homely, Copy as HTML Link.

So he created Copy as HTML Link for Firefox and generously shared his moment with wp-hackers Subscribers .

The plugin looks good and he did a really good job documenting it (THIS IS RARE!):

Click to go to the original site.

I must say that since I’ve started using this method, it’s been a quite a time saver. This was a GREAT idea. Inspired! So, if you have FireFox, please head on over there and get that plug-in!

Ah, but here’s the fly in the ointment and the sand in my… socks: A Firefox plugin won’t work for Maxthon!!!! (Click to go to the original site.) or Internet Explorer!

You see, Firefox just doesn’t do it for me. Click to go to the original site. Opera comes darn close to being right, but I like the extra usability features in Maxthon.

So, I thought… Hey… I could do that for Maxthon and IE AND I could do it all from a BATCH file!

So, here it is…

Run this Batch file and you will have installed on your system, two new menu items. When you highlight text, you’ll have an option to “Copy as Link” and when an image is right clicked, you will get an option to “Copy Image as Link”. Hopefully I’ve chosen hotkeys that will work well for you… If not, you can change them in RegEdit at HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\

BTW EVERY image and link up to this point in this post was created using this tool. Man, Good idea Justin!

Also - If you find that IE is prompting you asking for permissions to open the links, please post a comment and I’ll show how to fix that. I’ve gotten that message on other things I’ve like this I’ve created and know how to get past it. I’ve disabled that workaround on this computer and I am not getting that “Are you sure” message. So these menu items should be safe. ALSO, some popup blockers may block these items. You might have to add localhost as a site that is allowed to show popups in your particular popup blocker. Let me know if you have any problems.

Here’s the download: http://www.TheCodeCave.com/downloads/batch/AddCopyAsLink.bat

Here is the source:

DOS:
  1. @echo Off
  2. :: Implements "Copy * as Link" menu items in IE and Maxthon
  3. :: Written by Brian Layman
  4. :: Visit me at: http://www.TheCodeCave.com
  5. :: Version 0.1
  6. :: Update Url: http://www.thecodecave.com/?p=152
  7. :: Inspired by Justin’s Firefox Plubin
  8. :: Found at: http://justinsomnia.org/2006/05/copy-as-html-link-for-firefox/
  9.  
  10. :: Create file for the Copy Text as Link
  11. echo ^>%windir%\web\copytextaslink.htm
  12. echo ^<script language="JavaScript">>>%windir%\web\copytextaslink.htm
  13. echo var parentwin = external.menuArguments;>>%windir%\web\copytextaslink.htm
  14. echo var doc = parentwin.document;>>%windir%\web\copytextaslink.htm
  15. echo var sel = doc.selection;>>%windir%\web\copytextaslink.htm
  16. echo var rng = sel.createRange();>>%windir%\web\copytextaslink.htm
  17. echo var str = new String(rng.text);>>%windir%\web\copytextaslink.htm
  18. echo window.clipboardData.setData(‘Text’, ‘^<a href="’ + parentwin.location + ‘"^>’ + str + ‘^</a^>’);>>%windir%\web\copytextaslink.htm
  19. echo ^</SCRIPT^>>>%windir%\web\copytextaslink.htm
  20. echo ^</HTML^>>>%windir%\web\copytextaslink.htm
  21.  
  22. :: Create the menu context.
  23. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Te&amp;xt as Link" /ve /t REG_SZ /d "%WINDIR%\web\copytextaslink.htm" /f
  24. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Te&amp;xt as Link" /v Contexts /t REG_DWORD /d 16 /f
  25.  
  26. :: Create file for Copy Image as Link
  27. echo ^<HTML^>>%windir%\web\copyimageaslink.htm
  28. echo ^<SCRIPT LANGUAGE="JavaScript" defer^>>>%windir%\web\copyimageaslink.htm
  29. echo var parentwin = external.menuArguments;>>%windir%\web\copyimageaslink.htm
  30. echo var doc = parentwin.document;>>%windir%\web\copyimageaslink.htm
  31. echo var w;>>%windir%\web\copyimageaslink.htm
  32. echo var h;>>%windir%\web\copyimageaslink.htm
  33. echo var sel = doc.selection;>>%windir%\web\copyimageaslink.htm
  34. echo var rng = sel.createRange();>>%windir%\web\copyimageaslink.htm
  35. echo var str = new String(rng.text);>>%windir%\web\copyimageaslink.htm
  36. echo if ( parentwin.event.srcElement.tagName == "IMG" )>>%windir%\web\copyimageaslink.htm
  37. echo {>>%windir%\web\copyimageaslink.htm
  38. echo    h = parentwin.event.srcElement.height;>>%windir%\web\copyimageaslink.htm
  39. echo    w = parentwin.event.srcElement.width;>>%windir%\web\copyimageaslink.htm
  40. echo    window.clipboardData.setData(‘Text’, ‘^<a href="’ + parentwin.location + ‘"^>^<img src="’ + parentwin.event.srcElement.href + ‘" Width = "’ + w + ‘" Height = "’ + h + ‘" alt="Click to go to the original site."/^>^</a^>’);>>%windir%\web\copyimageaslink.htm
  41. echo }>>%windir%\web\copyimageaslink.htm
  42. echo else>>%windir%\web\copyimageaslink.htm
  43. echo    alert ("Incompatible element. Select either just an image or just text.");>>%windir%\web\copyimageaslink.htm
  44. echo ^</SCRIPT^>>>%windir%\web\copyimageaslink.htm
  45. echo ^</HTML^>>>%windir%\web\copyimageaslink.htm
  46.  
  47. :: Create the menu context.
  48. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Image as Lin&amp;k" /ve /t REG_SZ /d "%WINDIR%\web\copyimageaslink.htm" /f
  49. reg ADD "HKCU\Software\Microsoft\Internet Explorer\MenuExt\Copy Image as Lin&amp;k" /v Contexts /t REG_DWORD /d 2 /f
  50. :: Done
  51. cls
  52. Echo.
  53. Echo The Right-Click + "Copy * as Link" features have been added to Maxthon
  54. Echo and all other IE based browsers.
  55. Echo.
  56. Echo Please close and restart all browsers to complete the install.
  57. Echo.
  58. Echo Thank you for using this tool from TheCodeCave.com.
  59. Echo.
  60. Echo - Brian
  61. Echo.
  62. Echo.
  63. Echo.
  64. pause

Just let me know if you have any issues… It’s been working great for me!

April 6, 2006

How to: Creating a unique temporary file and determining the working drive and path

Filed under: Batch — Brian @ 11:05 am

This is a demonstration of how to use a TempFile in a .BAT or .CMD file. The goal of this example is to determine the relative path of the current working directory and assign it to a variable.

Concepts Demonstrated:


  • Generating a unique file names

  • Creating a temp file, using the Windows Naming convetion, and deleting it when done

  • Calling support subroutines in a batch file

  • Using GOTO :EOF to end exit a subroutine but not the batch file

  • Use of the command line “FOR” routine

  • Using Variables with “for /F”

  • How to get the current directory

  • Verbose and Quiet modes for a batch file

Temporary files are incredibly useful in batch files. When used in combination with a “For” loop, you can accomplish some amazing stuff from the command line.

In this example we assign a new file name to the TEMPORARY_FILE variable and then export the current working path to that file by echoing cd environment variable to it:

call :GETTEMPNAME
echo %cd%>%TEMPORARY_FILE%

Once our temp file has contents, the For routine can be used to parse each line and execute a command with the result. So, we use the For command to divide the working directory, lets say it is “C:\WorkingDir” into several peices (aka tokens):

FOR /F “tokens=1* delims=:” %%G IN (%TEMPORARY_FILE%) DO set RelativePath=%%H

Literaly we are telling it to break the line up at every colon ( : ), and to assign the first token to the variable %G. The asterisk (*) indicates that each token after that should be assigned to a new variable letter (H,I,J, and etc.). In our example, our %H will contain “\WorkingDir”.

“For /F” is really most usefull with larger files containing multiple lines. Since our file contains only one line with two tokens, the process stops there but you could, for example, parse all the names of files in a directory (dir *.xyz /b > %TEMPORARY_FILE%), or the contents of a registry key exported to that file using (REG QUERY [...] > %TEMPORARY_FILE%). I’ve used both of these methods in the past to do some really neat things that might have otherwise involved creating a custom executible. One advantage of doing it from teh command line is that it keeps the registry clean of all the garbage left behind by Windows anytime you run an exe.

Oh!

Something that is not often emphasized in “For /F” documentation is that it can parse variables as well as files. This could greatly optimize this example. Instead of parsing our file, we would simply put our %CD variable in quotes and call:

FOR /F “tokens=1* delims=:” %%G IN (”%CD%”) DO set RelativePath=%%H

We will get exactly the same results and can cut our batch file size in half! Of course, then we wouldn’t have a good example of temp file usage would we? So, we will do it the hard way.

Thus:
(more…)

March 22, 2006

A batch file to find the first matching file in the search path…

Filed under: Batch — Brian @ 12:49 am

This is another small app I wrote for someone to use at the ZTree forum.

This one is a DOS batch file that finds files in your search path that match the criteria you pass to it.
For instance you could type “SearchPath WPFile.Doc” and it would return the location of that file in your search path. If you type in simply “SearchPath MyApp” it will do a search for all executible files as defined by the PATHEXT environmental variable.

I found this program extremely useful since when clicking Start>Run and entering NO (it was supposed to autocomplete to notepad) ran a program that I could not find anywhere. SearchPath found it in a network directory.

Concepts Demonstrated:
Batch file subroutines - Use a CALL to execute a jump location in the same batch file as if it was a seperate batch
GOTO :EOF - Used to return out of a batch file OR batch Subroutine.
For Loops & Accessing to Environment variables
Child Recursion - A parent calls the child and the child in turn calls the parent which could in turn
child again.

DOS:
  1. :: *************************************************************************
  2. ::  SearchPath.Bat                                                                                            10/31/2005
  3. ::  Written by Brian Layman (AKA Capt. Queeg)
  4. ::  Visit him at http://www.TheCodeCave.com
  5. :
  6. ::  A batch written to display the program that would be run when
  7. ::  a filename is typed at the command prompt.  Just a demo for
  8. ::  Hartmut at http://www.ztw3.com/forum/forum.cgi
  9. :
  10. ::  Usage: SearchPath ProgramName[.EXT]
  11. :
  12. ::  History:
  13. ::     10/31/2005 - BL - Created
  14. ::     11/01/2005 - BL - Removed Temp File Usage
  15. :
  16. :: *************************************************************************
  17. @echo Off
  18. :: All this is boiled down to one subroutine that sets a variable of the
  19. :: same name.
  20. call :SearchedFilePath %1
  21.  
  22. :: If no program is found, say so.
  23. if "%SearchedFilePath%"=="" echo There is no matching program in the search path
  24.  
  25. :: If a program was found, echo its name.
  26. if NOT "%SearchedFilePath%"=="" echo %SearchedFilePath%
  27.  
  28. :: Clear out our temp variable
  29. set SearchedFilePath=
  30.  
  31. :: Quit
  32. GOTO :EOF
  33. :: *************************************************************************
  34.  
  35.  
  36. :: *************************************************************************
  37. ::  Support procedures
  38. ::
  39. ::  These routines are called with a CALL directive and the GOTO :EOF
  40. ::  terminates that CALL but does not terminate the entire running of the
  41. ::  batch file.
  42. :: *************************************************************************
  43.  
  44. :: *************************************************************************
  45. :SearchedFilePath
  46. ::  Returns the full path to a passed file in the searchpath
  47. ::
  48. ::  Returns blank if not found.
  49. ::
  50. :: *************************************************************************
  51. : set SearchedFilePath
  52.   :: Set the default value to blank.
  53.   set SearchedFilePath=
  54.  
  55.   :: If there is no extension handle it
  56.   if "%~x1"=="" Call :SearchWithExtensions %1&GOTO :EOF
  57.  
  58.   :: There is no extension, is it blank?
  59.   if "%1"=="" GOTO :EOF
  60.  
  61.   :: So, we have an extension.  That means we can do a simple search.
  62.   :: %~dp$PATH:1 automatically searches the path for us.  It is a
  63.   :: variable set by the Call command.
  64.   set  SearchedFilePath=%~dp$PATH:1%1
  65.   if "%SearchedFilePath%"=="%1" set SearchedFilePath=&GOTO :EOF
  66.   GOTO :EOF
  67. :: *************************************************************************
  68.  
  69. :: *************************************************************************
  70. :SearchWithExtensions
  71. ::  Iterates the extensions gathered from the PATHEXT environment
  72. ::  and searches until the file is found.
  73. ::
  74. ::  Returns blank if not found.
  75. ::
  76. :: *************************************************************************
  77.     :: Initialize a counter for looking at multiple search results in one line
  78.     set cnt=0
  79.  
  80.     :SearchLoop
  81.       :: Break out after 20  checks.
  82.       :: If you might have more than 20 extensions, increase this value.
  83.       :: If you could find out how many periods there are in the temp file,
  84.       :: you could optimize this.
  85.       if "%cnt%"=="20" GOTO :SearchLoopCleanup
  86.       set /A cnt=%cnt%+1
  87.       :: Continually search the single line file returning each sequential
  88.       :: search result and recursively pass it to the SearchedFilePath routine. 
  89.       :: When we ask for a token # that doesn’t exist and blank is returned,
  90.       :: abort out.
  91.       for /F "tokens=%cnt% delims=.;" %%C in ("%PATHEXT%") do call :SearchedFilePath %1.%%C
  92.       if "%SearchedFilePath%"== "" GOTO :SearchLoop
  93.    
  94.     :SearchLoopCleanup
  95.       :: Clear our Temp variable
  96.       set cnt=
  97.   GOTO :EOF
  98. :: *************************************************************************

March 1, 2006

A command line method to reattach to networks

Filed under: Batch — Brian @ 11:12 am

This routine does the same thing as the Windows Network Repair function, but from the command prompt.  Now why is this important? Well, it is VERY important when you have effected network changes, or physically had someone detach the computer from one network and attach it to another.  When this is done, the computer has to know to forget everything it knew about the old network and learn what it can from the new network.  Double clicking on a short cut to this batch file can take care of that and it is much simpler than leading someone through the steps to get to the network repair option.

Concepts Demonstrated: Network manipulation
Concepts Demonstrated: Quiet Parameter

      ::@Echo off ::************************************************************************* :: This Batch file performs the rough equivelant of a Windows XP SP1  :: Network Connection Repair. :: :: Usage: ::   NetworkRepair      <-- Prompts for permission & repairs all networks ::   NetworkRepair [ConnectionName]     <-- Prompts & repairs one network ::   NetworkRepair Quiet    <-- Does Not Prompt (Quiet is Case Sensitive) ::   NetworkRepair Quiet [ConnectionName]    <-- Repairs only one network :: :: A Windows Network Connection Repair (Right click on the Local Area  :: Connection and choose Repair) performs a series of commands that allows :: a computer to rebuild a its connection to the network.  The commands :: that are invoked by Repair are included below in their command-line :: equivalents.  The only current  difference is that the Repair process :: first checks whether DHCP is enabled and then, if enabled, it issues a :: broadcast renew to refresh the IP address.   This will cause the  :: computer to accept a lease from *any* DHCP server that is on the network.  :: You cannot do that from the command line.  In contrast, a unicast renew :: (as done through ipconfig /renew) will only renew the existing lease :: from the currently used DHCP server.  I've  t