Right Click, command prompts, batch files and all that jazz…..

Right clicking a folder or file in Windows Explorer presents a context menu which can be modified by programs or the user. I read a lot of posts on how to remove or disable items in the right click menu but not how to add an item.

This started with wanting to generate a list of files in a directory as a text file. This led me to a number of options including a how to on this with a right click menu option to launch it at the Elder Geek site.

This is the content of my filelisting.bat:
cd %1
dir /a /b /-p /o:gen >List_Files.txt
start notepad List_Files.txt

But this actually does not work as described. The action of right clicking on a directory generates a file list ok, but only of the contents of the containing directory not the selected directory. In other words it does not drill into the selected directory.

There is also an issue with Windows XP being different to Windows 7 as the end user interface to add items to the right click menu has been removed in Windows 7.

A lot of links recommend http://www.nirsoft.net/utils/shell_menu_new.html which I downloaded but I could not see or read how to Create a new Item with the tools only how to remove or disable options.

So I resorted to editing the registry directly and read a number of articles on how this could be done. The one at Tech Recipes was helpful.

The Microsoft listing of environment variables is a useful reference.

Eventually I wound up at Microsoft Support Article 321379 “How to add the Print Directory feature for folders in Windows XP, in Windows Vista, or in Windows 7” which is referenced by many other sites but not explained by any that I looked at.

The registry entries as described by Microsoft I reviewed as follows:

Windows Registry Editor Version 5.00

Must appear as the first line or the file will not be recognised as a registry merge file.

[HKEY_CLASSES_ROOTDirectoryShell]
@=”none”

This is simply setting up the container key in the registry. In my case it already existed from something else I had installed.

[HKEY_CLASSES_ROOTDirectoryShellCreate_File_Listing]
@=”Create File List”

This is the text that will appear in the right click menu when the context is a Directory.

[HKEY_CLASSES_ROOTDirectoryshellCreate_File_Listingcommand]
@=”filelisting.bat “%1″”

This is the command that will be executed when the right click menu item is selected (clicked on).

These three by themselves provide the facility that I needed so I did not create the rest of the entries. I’ve included them here for completeness and one day might get around to understanding what they do.

[HKEY_CLASSES_ROOTSOFTWAREClassesDirectory]
“BrowserFlags”=dword:00000008

Not sure what this does……

[HKEY_CLASSES_ROOTSOFTWAREClassesDirectoryshellCreate_File_Listing]
@=”Create File List”

This appears to repeat the previous menu name option. Removing the registry entry above and adding this one by itself does not display in the context menu. It might be redundant or might relate to the per-user class registration process described by Microsoft.

[HKEY_CLASSES_ROOTSOFTWAREClassesDirectoryshellCreate_File_Listingcommand]
@=”filelisting.bat “%1″”

[HKEY_CURRENT_USERSoftwareMicrosoftWindowsShellAttachmentExecute{0002DF01-0000-0000-C000-000000000046}]
@=””

[HKEY_CLASSES_ROOTSOFTWAREClassesDirectory]
“EditFlags”=”000001d2”

So now I had a working command structure in the right click context menu. But I could not work out how to get it to work unless I placed the filelisting.bat file in the c:windows directory. I tried using the full path to the file in my usersdocumentsbin directory which is where I store my .bat files and similar stuff (mainly so I can backup my specials and move them to a new PC easily) but no matter what I tried it refused to work unless the file was in the c:windows directory, so that is where it is.

Once the file would launch I could demonstrate that I now had the child directory parameter being passed to the bat file and I could generate the file list within the selected directory rather than it’s parent.

Other sites I referenced included:

  • http://commandwindows.com/batchfiles-iterating.htm
  • http://spreadsheetpage.com/index.php/tip/getting_a_list_of_file_names/
  • http://www.ericphelps.com/batch/lists/filelist.htm
  • http://www.tomshardware.com/forum/90764-45-calling-batch-file-context-menu-_multiple_-param
  • http://www.tech-recipes.com/rx/232/right-click-to-open-a-command-prompt/
  • http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/cmd.mspx?mfr=true

Windows IIS 7 removing PHP 5.2.8 and installing PHP 5.3.8

Seems like a simple enough task.

Remove the old PHP 5.2.8 and update via the Official Microsoft site a brand new 5.3.8 PHP version.

Never, never, ever assume!

For those of you that prefer a quick summary the removal of the PHP 5.2.8 via the Uninstall process does not remove / reset the environment variables of PHPRC or PATH. Further it does not remove the Fastcgi settings in the IIS console. Using the Microsoft Installer for PHP on Windows 2008 server does not adjust the environment variables for the new path and does not overwrite but adds new entries into the IIS configuration. The really painful and most time consuming issue was that the installer for Microsoft does not automatically include extensions for MS-SQL, only MySQL !!!

The slightly longer version with links and details follows. Suffice to say at this point if you have found this whilst trying to install SugarCRM, PHP 5.3.8 to work with Windows Server 2008 and IIS 7 then it really is relatively simple once you get past the ‘I would have expected that……’ thought process.

Use the Windows Installer for PHP the current one is 5.3.8 If you dont have the Web Platform Installer it will trigger that installation first. There is information on the learniis pages that provides more detail.

Modify the environmental variables – if upgrading remove / modify the existing – for a first time install add the PHPRC if necessary.

Control Panel -> System and Security -> System -> Advanced System Settings -> Environment Variables

Select in the System Variables lower panel not the User Variables in the upper panel.

Insert the path, in my case it is C:Program Files (x86)PHPv5.3, to the PHP installation as the first element in the Path command. This saves the system from trawling through all the other application paths and adds minimal overhead for the other applications as there are only a relatively small number of files to check in the PHP directory.

Insert the PHPRC variable and set the same path C:Program Files (x86)PHPv5.3

To test that this is working open a new command window (Start -> Run -> cmd: but if you need this you probably are out of your depth!) and type php -v at the prompt. You should get back a PHP 5.3.8 information text. If you get a not found error then you need to check your install and variable paths actually match.

In the IIS console at the server level open the Handler Mappings icon and confirm that there is only one PHP entry – default should be PHP53_via_FastCGI. Remove any other PHP entries.

In the IIS console at the server level open the FastCGI icon and confirm that there is only one entry there as well. Remove any other than the 5.3.8 entry. There should be only one.

At this stage the IIS console should show a PHP Manager icon in the server page. Checking the phpinfo() page will confirm that PHP is running ok.

The next bit is what caught me. It was an existing SugarCRM -> MSSQL install that was working (albeit with other issues) but I kept getting Error 500 Internal Server Errors when I tried to run the old Sugar install. Using phpinfo() pages worked so it was not a PHP issue. There was no PHP error log message, and nothing in the Event Viewer.

It was only during some testing that I tried installing a fresh copy of SugarCRM to establish if the issue was something corrupted in the existing application. The installer ran through its checks and offered for me to select the database driver. But, the only option was MySQL. That was my Duh! moment. Checking back on the PHP install and doing some extra reading confirmed that the earlier 5.2.8 install had the MS-SQL drivers while the 5.3.8 doesn’t automatically include them. You would think that a Microsoft prepared installer would have MS-SQL as a preferred database, but no it’s a separate install. Which explains the odd Internal Server Error 500 when trying to use the SugarCRM application. It could not get to the database as the PHP drivers did not exist.

Refer to the learniis page for installing the SQL Drivers but it points to v1.0 of the drivers. Use the following link for version 2.0

Downloading the Microsoft SQL Server drivers for PHP currently version 2.0.

Select the correct .dll for the installation, VC9 Non-Thread-Safe, for both the SQL and PDO_SQL (PHP Data Objects) and copy these to the PHP extensions directory C:Program Files (x86)PHPv5.3ext

Finally, using the IIS console PHP Manager at the server level, enable these additional extensions. I restarted the IIS for good measure and SugarCRM is working again.

SugarCRM IIS 7.5 PHP Windows Server Exchange combined

When combining server roles to perform many tasks with one server there is a lot of potential for things to trip over themselves.

This started as a simple ‘Provide an LDAP connection between SugarCRM and Active Directory’.

Issue: Configuring the LDAP settings for SugarCRM is relatively easy but when trying to test by setting a specific user to ‘Use only LDAP Authentication’ the SugarCRM login page reports that the LDAP extensions are not loaded. Ok, so its a PHP config issue.

Issue: The PHP error log shows that not only is LDAP an issue but also CURL and a few other PHP extensions are not loading. With a ‘File not found’ error.

The extension files are all there, the paths are correct, etc. The issue appears to be that some supporting files are missing including libeay32.dll and ssleay.dll, so preparing a fresh install of PHP with these options enabled adds the files to the PHP directory. But the error persists.

Issue: PHP 32 bit not 64 bit so we need to set the Application Pool to allow for 32 bit applications. But this triggered another series of issues.

Issue: Attempting to set 32 bit for any App Pool on the server crashes with errors.
The browser returns an error 500 Internal Server Error.

The Application Event Viewer showed

Log Name: Application
Source: Microsoft-Windows-IIS-W3SVC-WP
Event ID: 2282
Task Category: None
Level: Error
Keywords: Classic
User: N/A

The Module DLL ‘C:Program FilesMicrosoftExchange ServerV14Binkerbauth.dll’ could not be loaded due to a configuration problem. The current configuration only supports loading images built for a x86 processor architecture. The data field contains the error number. To learn more about this issue, including how to troubleshooting this kind of processor architecture mismatch error, see http://go.microsoft.com/fwlink/?LinkId=29349.

Which led me to Chris’s Blog and issues with setting 32 bit apps on an OWA server. Following those instructions which can be summarised as follows:

  • Stop the IIS Service
  • Edit C:WindowsSystem32inetsrvconfigapplicationHost.config
  • Edit the following 3 lines to append/insert the preCondition=”bitness64″ option
  • <add name=”kerbauth” image=”C:Program FilesMicrosoftExchange ServerV14Binkerbauth.dll” preCondition=”bitness64″ />
  • <filter name=”Exchange OWA Cookie Authentication ISAPI Filter” path=”C:Program FilesMicrosoftExchange ServerV14ClientAccessowaauthowaauth.dll” enabled=”true” preCondition=”bitness64″ />
  • <filter name=”Exchange ActiveSync ISAPI Filter” path=”C:Program FilesMicrosoftExchange ServerV14ClientAccesssyncbinAirFilter.dll” enabled=”true” preCondition=”bitness64″ />
  • Start the IIS Service
  • Set an Application Pool to use 32 bit Applications
  • This resolved the 32 vs 64 bit war and brought me back to the PHP issues that started this.

    Issue: Curl and other extensions not loading.

    So I tried running php from the command line

    D:Applicationsphp> C:progra~1phpphp-cgi.exe
    PHP Warning: PHP Startup: bz2: Unable to initialize module
    Module compiled with module API=20060613, debug=0, thread-safety=0
    PHP compiled with module API=20060613, debug=0, thread-safety=1
    These options need to match
    in Unknown on line 0
    PHP Warning: PHP Startup: Unable to load dynamic library ‘C:Program Files (x86
    )PHPextphp_curl.dll’ – The specified module could not be found.
    in Unknown on line 0
    PHP Warning: PHP Startup: dba: Unable to initialize module
    Module compiled with module API=20060613, debug=0, thread-safety=0
    PHP compiled with module API=20060613, debug=0, thread-safety=1
    These options need to match
    in Unknown on line 0

    So this suggests that it is not a missing file or path but the thread-safety option which is weird as everything I have read including the name of the download is ” PHP Non-Thread Safe” so why would the installer be installing a modules compiled differently to the PHP install? I will probably never know. I gave up at this point and removed PHP 5.2.8 completely and installed 5.3.8 via the Microsoft Installer for PHP which enabled curl and ldap but led to a whole different world of pain.

    PHP mySQL osCmax and converting databases

    This week I started looking at the conversion of some older osCommerce databases and moving to osCmax. I’m almost on top of the templating but need to look at getting live data into the system to work with the templates.

    This post is not about that but about the bits of code that I’ve worked on to get my converter working.

    Connecting to two databases

    Stackoverflow came to my aid again! The post on PHP connecting to two databases seemed fine but I did not read completely the first (or second) time and only after doing a decent read realised that there was the additional parameter for a new connection. Setting that worked fine.

    There was also interesting reading on the logic and best practice around opening and closing database connections.

    Over at http://net.tutsplus.com/ there are some best practices for php and mysql coding.

    Altering a column in a table

    I picked up a script from EdmondsCommerce (nice play on eCommerce!) and the script worked fine. I then liked the concept of the script posted by Arnan in the comments to the post but that did not work. I also noted the comment to use ‘IF NOT EXISTS’ except that is only valid for tables not for columns, at least not in my reading.

    Adding a new column in a table

    Following on from the alter script I created a new function and modified Arnan’s code to work and dealt with some potential issues with columns existing or not. Which led me to……

    Logging Whats Happening

    Using ‘echo’ to the screen is the common debug process for PHP code. But in this case I am building something a bit more robust and potentially big once I get to grips with over 100 tables in the databases.

    I think an interactive script presenting information to the screen is good but not as a long scrolling list. I’d prefer to see a screen that sits and presents the current processing. In addition I want a log file to report on all actions and a separate log for the data line items just in case.

    So I am now on the hunt for error logging and reporting and a great start is this post about a Logging class from http://www.redips.net/php/write-to-log-file/ that I have left as is and it works a treat.

    Next I will need to come back to progress indicators like http://valums.com/ajax-upload/ and maybe here http://www.tutorialized.com/view/tutorial/PHP-GD-Progress-Bar-Demo/779 or http://davidwalsh.name/progress-bar-animated-mootools. The issue with this is how to update client side the progress occurring server side during a database table pass that in theory is either 0% or 100% and no feedback in between without splitting the query into segments and passing a client-side update. Needs more thought.