Showing posts with label Microsoft Windows. Show all posts
Showing posts with label Microsoft Windows. Show all posts

Saturday, October 1, 2011

Fixing UPnP/DLNA sharing on 2nd drive under Windows 7

Background

Though I may be a few years late to the party, I finally have a capable Home Theater PC (HTPC) and HDTV setup in my living room. For simplicity for the entire family, it's running Windows 7's Media Center.

My favorite feature of a HTPC-solution is the digital video recorder (DVR) functionality - including the options to pause and replay live TV. My family previously had a hard-drive enabled DVD player / DVR with this functionality built-in - but without an ATSC digital tuner, its use is now limited to analog cable. I since had a newer Philips DVD player / DVR with similar features - including an ATSC digital tuner - but it was only standard-definition (SD), not high-definition (HD), and recorded content had issues with volume levels as well as not supporting closed captioning and other broadcast features.

Disappointingly, these types of devices are appearing to be pushed out of the market in favor of versions that require monthly fees. Other than a new subscription to Netflix and our DVDs, most of what we watch is free broadcast television - without paying monthly fees for cable or satellite television service. I'm excited to have a HTPC-based DVR that is also fee-free. Much of the broadcast television we watch is also in HD, for free - something most paid-for TV services are still behind in for not offering without yet additional fees!

Besides having a direct HDMI connection between the PC and the TV, both devices support UPnP/DLNA. I'll prefer the HDMI connection as the primary link between the HTPC and its connected TV - mostly as it doesn't require to have an extra encode/decode step to stream the video over Ethernet. The DLNA method is also missing a few features that are natively available from the HTPC - including some simpler features such as closed captioning. However, the DLNA feature is certainly nice to have as a convenience for quickly streaming videos, pictures, or music from any other computer connected to the network - without needing to first add a wired connection, or otherwise transfer the media to a USB flash drive or another connected device.

UPnP/DLNA issue

I ran into some difficulties, however, when trying to stream content from my primary laptop - also running Windows 7 x64, Professional. My laptop simply would not show itself as a media server device. It wasn't a problem with the TV, as other clients on the network could also see all the other servers - just not my laptop. I eventually found that I could create new user accounts in Windows, and then my laptop became visible as a server - but only for the new user accounts, and not my primary user account. Unfortunately, this was something a bit more complicated than adjusting the "Media streaming options" in the Control Panel for my user account.

UPnP uses Simple Service Discovery Protocol (SSDP) for discovery. Not finding anything significant within the Windows Event Log, and not finding any other tools within Windows that could help troubleshoot the issue, I used Wireshark to try to determine what was causing the issue. I found several SSDP HTTP NOTIFY packets, with a URL of something like http://[fe80::5ddf:5cb8:a7e1:bbcb]:2869/upnphost/udhisapi.dll?content=uuid:eb1c9c01-e5c3-4eea-bea2-d9f0a6fb2bcf. Following the URL, XML was returned that described the media servers for all other media servers and users on the network - including from my own laptop, but not for my primary user account. This confirmed that the issue was with my server, and not the network or clients.

I eventually ran across several posts of other users having very similar symptoms, including:

Unfortunately, they were all unanswered (both replied to - especially with many non-solutions to the first). However, they all had something in common with my laptop setup: The user profile directory was moved off of the system drive. This should be a common setup - using disk partitions to separate the user data from the program data. Another common scenario for this today is to have the OS on a high-performance SSD, and a larger HDD for the user data. However, as Windows doesn't easily provide for configuring this setup, it isn't surprising that this isn't a more visible issue.

My Solution

In both threads, the users seemed to infer that the problem must have been in the file copy / move of the user profile directory between drives. Fortunately, at least in my case, this had nothing to do with the content of the files - but with the security permissions / Access Control Lists (ACLs).

Even after moving my user profile to a new drive / partition, folders such as "My Videos" have an added "Read" permission granted to "WMPNetworkSvc" (which is obviously the account for the "Windows Media Player network service"). This permission does not exist on (nor does it need to exist on) parent folders. However, there is a quirk in Windows where at least limited access needs to be granted to the root of the hosting drive, otherwise accounts can't access any data within the drive - regardless of what child ACLs may be present. This was not an issue on the C:\ drive, as by default, the "Read" permission is granted to "Users", and additionally has other special permissions granted to "Authenticated Users" - both which should apply to the "WMPNetworkSvc" account. Such permissions, however, did not exist on my data drive - which only had permissions defined for my personal account, the "Administrators" group, and the "SYSTEM" group.

The fix is rather simple - give the "WMPNetworkSvc" limited access to the root of the alternate drive hosting the user profile. By limited, I'm not kidding - and keeping access to the absolute minimum only follows best security practices. (You'll need to use the "Advanced" button to open the "Advanced Security Settings" dialog for this):

  1. From the drive properties, "Security" tab, click "Advanced".
  2. From the "Advanced Security Settings" dialog, on the bottom of the "Permissions" tab, click "Change Permissions...".
  3. On the 2nd dialog that pops-up, click "Add...".
  4. Type in "NT Service\WMPNetworkSvc" (without the quotes), click "Check Names" to make sure it is recognized, then click "OK".
    • The "NT Service" prefix is necessary to resolve the Windows service account. There is no other known way to be able to select it through the UI options.
  5. In the "Permission Entry" dialog that pops-up:
    1. Under "Apply to", select "This folder only".
    2. Under "Permissions:", check only the "Allow" checkbox for "Traverse folder / execute file".
    3. Click "OK".
  6. Click "OK" to close all 3 remaining dialogs.
  7. Restart the "Windows Media Player Network Sharing Service" (WMPNetworkSvc) Windows service.

All of the above UI steps can also be easily replaced with the following commands. Simply replace "D:\" with the drive letter that the Windows Media Player network service needs access to:

icacls D:\ /grant "NT Service\WMPNetworkSvc":(X)
net stop WMPNetworkSvc
net start WMPNetworkSvc

This is certainly not meant to nor will this help fix the many different types of issues that exist with network media sharing. However, hopefully this will benefit those who have organized their systems on to separate drives or partitions, and are experiencing the same issue.

Wednesday, August 19, 2009

Scripted hiding of Windows Updates under Vista

Similar to my last post, here is another UI issue with Windows Vista. Fortunately, this time I have a solution to offer.

Starting with Windows Vista, the "Windows Update" functionality is provided through Control Panel rather than Internet Explorer. In both versions, there is the ability to hide updates. While hidden updates can easily be restored, this feature allows for ignoring unnecessary updates so that they don't continually count towards the number of available updates that are displayed. For me, this includes the 34 "Windows Vista Ultimate Language Packs" that are currently available. Unfortunately, multiple-selection is not enabled in the "View available updates" dialog. There are checkboxes, including a checkbox on the header that can be used to select/unselect all shown updates, but the checkbox selections are used for the "Install" button only. The other options available from the context menu - "View details", "Copy details", and "Hide update" - can currently be applied only one-at-a-time. This means that hiding just the 34 language packs would require no fewer than 68 clicks!

Originally, I assumed that these hidden updates and other preferences would be stored in the Windows registry, or possibly in a file on the file system. They are in a file, but a database-type file that isn't directly editable: %SystemRoot%\SoftwareDistribution\DataStore\DataStore.edb. Fortunately, there is a comprehensive Windows API for viewing and editing this information, and it is even easily available to scripting through the Windows Scripting Host and languages such as JScript. Microsoft's reference is located on MSDN: Windows Update Agent API.

Here is my resulting script that automatically hides all the "Windows Vista Ultimate Language Packs":

var updateSession = WScript.CreateObject("Microsoft.Update.Session");
var updateSearcher = updateSession.CreateUpdateSearcher();
updateSearcher.Online = false;

var searchResult = updateSearcher.Search("CategoryIDs Contains 'a901c1bd-989c-45c6-8da0-8dde8dbb69e0' And IsInstalled=0");

for(var i=0; i<searchResult.Updates.Count; i++){
  var update = searchResult.Updates.Item(i);
  WScript.echo("Hiding update: " + update.Title);
  update.IsHidden = true;
}

If you're not familiar with WSH, this can be simply executed as saving it as a *.js file, then double-clicking. A better option is to execute the file from a command-line with cscript. This will cause the output messages to be written to the standard output, instead of popping up a message box that must be acknowledged for each message. Also, since this script is making administrative changes to the system, it must be executed as an administrator.

"a901c1bd-989c-45c6-8da0-8dde8dbb69e0" is the ICategory.CategoryID for "Windows Vista Ultimate Language Packs". (This ICategory happens to have a .Type of "Product".) A similar script can easily be used to perform operations on other sets of updates by simply modifying the search query.

For the above example, the changes can be reverted by updating the script to executed update.IsHidden = false; (instead of true), then re-executing the script. Alternatively, here the Windows Vista GUI works a little better: By clicking on "Restore hidden updates" from the side panel in Windows Update, the "Restore" button operates on the checkbox selection - allowing all hidden updates to quickly be restored with 2 clicks if desired.

Finally, here is an extended example that doesn't change anything, but displays some of the many details that are available through this API. First, it displays all the updates grouped and nested by category. Note that some updates belong to more than one category. Finally, it displays all available updates in a "flat" view, without using categories.

var updateSession = WScript.CreateObject("Microsoft.Update.Session");
var updateSearcher = updateSession.CreateUpdateSearcher();
updateSearcher.Online = false;

var searchResult = updateSearcher.Search("IsInstalled=1 or IsInstalled=0");

var describeCategory = function(cat, depth){
  var pad = new Array(depth + 1).join("  ");
  WScript.echo(pad + depth + ": " + cat + ", " + cat.CategoryID + ", " + cat.Name + ", " + cat.Type);

  for(var i=0; i<cat.Children.Count; i++){
    var child = cat.Children.Item(i);
    describeCategory(child, depth + 1);
  }
  
  for(var i=0; i<cat.Updates.Count; i++){
    var update = cat.Updates.Item(i);
    WScript.echo(pad + "  " + describeUpdate(update, pad + "  "));
  }
};

var describeUpdate = function(update, pad){
  var u = update;
  var np = "\n" + (pad || "") + "  ";
  return u.Title
    + np + "Type: " + u.Type
    //+ np + "Description: " + u.Description
    + np + "IsInstalled: " + u.IsInstalled
    + np + "IsDownloaded: " + u.IsDownloaded
    + np + "IsHidden: " + u.IsHidden
    + np + "AutoSelectOnWebSites: " + u.AutoSelectOnWebSites;
};

for(var i=0; i<searchResult.RootCategories.Count; i++){
  var category = searchResult.RootCategories.Item(i);
  describeCategory(category, 1);
}

WScript.echo("\n");

for(var i=0; i<searchResult.Updates.Count; i++){
  var update = searchResult.Updates.Item(i);
  WScript.echo(describeUpdate(update));
}

According to the IUpdateSearcher.Search documentation, the default search criteria is "IsInstalled = 0 and IsHidden = 0". Unfortunately, there doesn't seem to be a simple option to short-circuit the evaluator to just return all available updates, e.g. "" or "1=1". So far now, "IsInstalled=1 or IsInstalled=0" results in all updates being displayed. The only other note concerning the above example is that the "description" line is commented out in the describeUpdate function only because it can be rather verbose, and make the overall output difficult to read. Feel free to uncomment it to view the details, as well as adding additional lines for all the other properties available from IUpdate.

Sunday, August 9, 2009

IME and other Vista Start Menu Annoyances

Recently I noticed some context menu items under Windows Vista that I didn't previously recall. I first noticed this after right-clicking on the text box on the start menu. However, these items appear on most text-input fields, including Notepad, any of the text fields in the default File Open/Save dialog boxes from almost any application, or even right-clicking on the text while renaming a file from Windows Explorer. The complete context menu displayed is shown below:

Right to left Reading order, Show Unicode control characters, Insert Unicode control characters, Open IME, Reconversion

These extra items - "Right to left Reading order", "Show Unicode control characters", "Insert Unicode control character", "Open IME", and "Reconversion" - practically double both the width and the height of the context menu. To make things even more annoying, there doesn't appear to be any way to disable even the display of these items.

IME stands for Input Method Editor, which should allow for the input of additional characters and symbols that may not be found on the keyboard. However, the "Open IME" option doesn't even appear to function - even though clicking it toggles the option between "Open IME" and "Close IME". I've also never seen the "Reconversion" item enabled, even when text is selected. I don't even know what it is for. While "IME" contains a short 1-sentence definition in the Windows Help, searching for "reconversion" doesn't give any results. (Regardless of the menu functionality, a user should still be able to input any character code through the use of "alt codes".)

At first, I thought I accidentally installed an additional language pack, which is method that would have added these items under previous operating systems such as Windows XP. Another thought was that these options were introduced with Windows Vista Service Pack 2, or that I had accidentally installed a SP2 version designed for multiple languages. However, I found that these options are immediately available in default installations of Vista, including both the English Ultimate and Business editions.

I was a bit surprised at how few results related to this menu and Windows Vista show up on Google. Most of those are several years old (around 2007), the most comprehensive and recent of which I found on this forum thread. None that I've found contain any solutions, and apparently these menu items still exist in Windows 7 as well.

Start Menu size / width

Another issue I just noticed is that Vista's new start menu is not at all resizable, and is sometimes too small / too narrow to display items with longer names. To make matters worse, there are no scroll bars or other apparent functionality for viewing the cut-off text. This is even the case with some of Microsoft's own programs and installed shortcuts. For example, the last 2 characters of "Microsoft Windows Performance Toolkit" do not fit within the fixed width of the "All Programs" menu.

Unfortunately, again, there doesn't appear to be any resolution or reasonable work-around to this issue, short of renaming the longer names to shorter ones. The two most relevant pages I found from searching the web are this forum thread, and this Microsoft Answers forum thread where a Microsoft support engineer's response is only to switch to the classic Start menu instead.

In summary...

"UI blunders"?

Thursday, June 25, 2009

JScript for Ping, Renew IP and Network Info / Repair

I was having a frustrating issue where a remote Windows XP computer that I need to Remote Desktop into would occasionally become unresponsive. This issue already required me to drive a number of late-night trips to temporarily remedy the issue. While I've not yet found the root cause, the main issue seems to be that something becomes "disconnected" between the network adapter and the operating system. While the Windows "Status" dialog on the network adapter shows "Connected" and packets being sent and received, I am not even able to ping the default gateway. Windows Firewall is not enabled. The only other suspect software I need to rule out yet is an anti-virus service. Rebooting the computer always helped, but is rather drastic. Choosing the "Repair" option does not work, and shows a message about failing while renewing the IP address. Interestingly, the fastest temporary "fix" I found is to run "ipconfig /release" followed by "ipconfig /renew".

While this computer is probably due for a re-installation, it is not an immediate option. In the meantime, I came up with a Windows Script Host (WSH) script to automatically detect and repair this issue.

Update: The root cause is certainly related to "Symantec Endpoint Protection" 11.0.x (Antivirus). If Symantec is completely removed, the problem disappears. When reinstalled, the problem comes back. The "Network Thread Protection Logs" would show everything being blocked without reason, until reset by an IP renew or a reboot. (The "Rule" cited is either "Block local file sharing", even though it blocks ALL ports - or "Block all other traffic".) At least at one point, this was affecting dozens of desktops. However, Symantec needs to stay per corporate policy...

As previously posted, I chose to use JScript for this task (particularly over VBScript). Everything but the logging is essentially WMI (Windows Management Instrumentation) calls. If I hadn't coded for all of the extra logging, the code would have probably been less than half the current size. It basically finds a given network adapter, and attempts to ping the configured default gateway. If unsuccessful, it will perform a DHCP release and renew operation.

/** 
 * @author Mark A. Ziesemer, www.ziesemer.com, 2009-06-25
 */
(function(){
  
  var fso = new ActiveXObject("Scripting.FileSystemObject");
  var wmi = GetObject("winmgmts://localhost/root/cimv2");
  
  var getNetworkAdapter = function(name){
    var adapters = new Enumerator(wmi.ExecQuery(
      "Select * From Win32_NetworkAdapter Where NetConnectionID='" + name + "'"));
    if(!adapters.atEnd()){
      return adapters.item();
    }
  };
  
  var getAdapterConfig = function(index){
    var configs = new Enumerator(wmi.ExecQuery(
      "Select * From Win32_NetworkAdapterConfiguration Where Index=" + index));
    if(!configs.atEnd()){
      return configs.item();
    }
  };
  
  var ping = function(host){
    var results = new Enumerator(wmi.ExecQuery(
      "Select * From Win32_PingStatus Where Address = '" + host + "'"));
    if(!results.atEnd()){
      var result = results.item();
      return result.StatusCode;
    }
  };
  
  var logWriter = fso.OpenTextFile("PingTest.log", 8, true);
  try{
    var log = function(msg){
      logWriter.WriteLine(new Date() + " - " + msg);
    };
    
    var adapter = getNetworkAdapter("Local Area Connection");
    if(adapter){
      log("Found network adapter:"
        + "\r\n\tAvailability: " + adapter.Availability
        + "\r\n\tCaption: " + adapter.Caption
        + "\r\n\tConfigManagerErrorCode: " + adapter.ConfigManagerErrorCode
        + "\r\n\tErrorDescription: " + adapter.ErrorDescription
        + "\r\n\tLastErrorCode: " + adapter.LastErrorCode
        + "\r\n\tMACAddress: " + adapter.MACAddress
        + "\r\n\tName: " + adapter.Name
        + "\r\n\tNetConnectionID: " + adapter.NetConnectionID
        + "\r\n\tNetConnectionStatus: " + adapter.NetConnectionStatus
        + "\r\n\tStatus: " + adapter.Status
        + "\r\n\tTimeOfLastReset: " + adapter.TimeOfLastReset);
    }else{
      log("No suitable network adapter found.  Quitting...");
      return;
    }
    
    var adapterConfig = getAdapterConfig(adapter.Index);
    if(adapterConfig){
      log("Found network adapter config:"
        + "\r\n\tIPAddress: " + adapterConfig.IPAddress.toArray()
        + "\r\n\tDefaultIPGateway: " + adapterConfig.DefaultIPGateway.toArray());
    }else{
      log("No suitable network adapter configuration found.  Quitting...");
      return;
    }
    
    var pingResult = ping(adapterConfig.DefaultIPGateway.toArray()[0]);
    log("Ping result: " + pingResult);
    if(pingResult){
      var releaseResult = adapterConfig.ReleaseDHCPLease();
      if(releaseResult){
        log("Unexpected ReleaseDHCPLease() result: " + releaseResult);
        return;
      }
      var renewResult = adapterConfig.RenewDHCPLease();
      if(renewResult){
        log("Unexpected RenewDHCPLease() result: " + renewResult);
        return;
      }
      log("Successfully released and renewed IP: " + adapterConfig.IPAddress.toArray());
    }
  }finally{
    logWriter.WriteLine();
    logWriter.Close();
  }
  
})();

I added it to the Windows Task Scheduler, and set it to run every 5 minutes. While not available through the Windows UI, the schtasks command allows for scheduling as the "SYSTEM" user, assuming you have administrative rights. This eliminates the need for your password, and prevents the job from breaking when you change your password:

> schtasks /create /tn "PingTask" /tr "cscript C:\<path>\PingTest.js" /sc MINUTE /mo 5 /st 00:00:00 /ru System
INFO: The Schedule Task "PingTask" will be created under user name ("NT AUTHORITY\SYSTEM").
SUCCESS: The scheduled task "PingTask" has successfully been created.

While the problem detection isn't based on the packet count statistics that I observed from the Windows UI, I thought it would also be useful information to log to see if there is a correlation to the "disconnects". Unfortunately, I couldn't find an easy way to obtain these statistics - either through WMI or the command line. I did find a few places to obtain protocol/transport-level statistics such as TCP, but nothing at the link-layer (Ethernet) level. The only involved discussion I could find on this was this newsgroup posting to microsoft.public.win32.programmer.wmi back from 2006 which implies that these statistics are only available through native code.

Saturday, December 13, 2008

Backups, Re-installation, Free Software Checklist

I feel like a post like this is a number of years overdue for me. Especially for those of you I've done computer work for, this is basically a copy of the mental checklist I use when reformatting and reinstalling a Windows PC.

To quickly summarize, many computers can benefit from an occasional reformat and re-installation - especially if it seems to be running slow or if a computer virus or other malware is suspected. Given the complexity of much of today's malware, you can't realistically rely on your anti-virus software to catch everything, much less properly undo and repair things after an infection - no matter what the manufacturers claim. The best solution is to never get infected in the first place. Following "safe computing" practices is critical, which I'll save another post for. Even without an infection, reinstalling from the operating system-up can help by getting the latest features and other updates for all your software.

This is primarily meant as a list of items to consider and be aware of, and is not meant to be a complete step-by-step guide. Things will vary by your computer, desired software, and your needs. If you're not confident in what you're doing, get some assistance. If you don't already know someone who can help, ask around - word-of-mouth references are the best. A local computer repair shop is the next best-bet. I personally do not recommend Best Buy's Geek Squad or other similar services by other large, chain retailers. For anyone in the area of my previous home in Green Lake, WI, I'd recommend Badgerland Computer Systems. In Eau Claire, WI, I'd recommend RAM Technologies.

Backing Up

The first, and most important step is ensuring you have a proper, up-to-date backup of anything you want to save. Typically, you only need to worry about data, or files that are user-created. Programs can be reinstalled from CD/DVD or downloaded online. Backing up everything in the "Documents and Settings" folder is a good starting point, which is usually "C:\Documents and Settings", or "C:\Users" under Windows Vista.

Be aware some of these files will usually be in use, especially for the current user, and can't simply be copied while in-use. Use one of the following options:

  • Boot from a Live CD, such as Ubuntu's LiveCD or BartPE (direct).
  • Remove the hard drive, connect it to another computer, and use that computer's operating system to copy the files. (Don't simply boot the hard drive on another computer's hardware.) A Disk enclosure or other adapter may be helpful / required for this. Sunbeam's SATA IDE to USB Adapter has worked well for me, and can be purchased from Newegg and elsewhere for only about $20.
  • Use backup software that supports Shadow Copy, which includes Microsoft's NTBackup and Vista's Windows Backup applications.
  • As a last resort, backup using a secondary user account. Logging-out the first user doesn't always sufficiently close all open files, particularly ntuser.dat, so rebooting before logging in as the second user is recommended.

Writable DVDs are cheap and usually work well. Just be aware that they are quite fragile. USB flash drives and external hard drives can also be used. I've often considered trying Iomega's REV Drive (Wikipedia). Regardless of the media, consider and choose a backup rotation scheme. Especially, consider if something were to happen while a back-up was in progress - is there a previous and suitable backup available? Keeping one or more recent off-site copies is also a necessity.

Review other considerations and concepts at Wikipedia's Backup article.

Re-installation

1) Verify that you have a proper backup (above), re-installation CD/DVDs for all your programs, and any critical drivers on a CD or other removable media for reinstalling the network drivers, etc.

2) Check for and apply any BIOS updates.

3) Reinstall the operating system.

  • Use a slipstreamed installation disk with the latest service pack and updates if possible. For Microsoft Windows XP, I recommend using RyanVM. Additional guides are readily available via a Google search: "slipstream windows xp sp3".
  • Consider partitioning the drive into separate partitions, at least one for the operating systems / programs, and one for user data. This allows for the possibility of reformatting and reinstalling the OS partition in the future without loosing user data - though this should not replace backing up.

4) Use Windows Update/Microsoft Update to install any available security and other critical updates. The process may need to be repeated until no further updates are available.

5) Install any needed device drivers and other system utilities.

6) Re-install any needed applications / programs.

7) Restore data from backup.

Free Software Checklist

Finally, make sure your computer can do everything you expect it to do by getting the necessary software. Everything below is "free" as in zero-cost. Additionally, a significant portion of this list is Free Software / Open Source, meaning that it "is software that can be used, studied, and modified without restriction, and which can be copied and redistributed in modified or unmodified form either without restriction".

Unless otherwise noted, everything here should work on Windows XP 32-bit, and both the 32-bit and 64-bit versions of Windows Vista. (I'm using the 64-bit version of Windows Vista, and have everything below installed and working.)

First are some applications that should probably be installed on any new computer, regardless of user. These are frequently required on the web and for opening common file formats, and will eliminate a near-future need to find and install the necessary program later.

  • Mozilla Firefox (web browser) [direct].
    • Especially for more technical users / developers, review my previous post of Firefox extensions.
  • Adobe: (all proprietary)
  • The latest Java Runtime Environment [direct].
    • Developers should also install the Java Development Kit (JDK).
  • Apple QuickTime (media player) [direct] (proprietary).
  • VLC media player [direct]. Plays DVDs, and just about any other media format.
  • The Xvid video codec [direct], for playing Xvid, DivX, and similarly-encoded video files.
  • The GIMP image editor [direct].
  • 7-Zip file archiver [direct].
    • While Windows provides built-in support for regular .zip files, 7-Zip provides extended options and better performance, and supports a wide variety of additional archive formats.
  • InfraRecorder CD/DVD writing (burning) software [direct].
  • OpenOffice.org office suite [direct].
  • Avast! anti-virus home edition [direct] (proprietary).
    • Alternatively, AVG Anti-Virus Free Edition (proprietary).
  • For Windows XP only, the Microsoft PowerToys for Windows XP. Particularly: Tweak UI, Image Resizer, Power Calculator, Open Command Window Here, and the Alt-Tab replacement (all proprietary).
    • In Windows Vista, the Windows XP-version of Tweak UI will not work. Look at the basic version of TweakVI instead.
    • In Windows Vista, the "Open Command Window Here" is already included. Just hold-down the shift key while right-clicking on or in a folder.
    • In Windows Vista, the "Alt-Tab replacement" is essentially built-in to Windows Aero.
  • The Sysinternals suite (proprietary). Download the "Sysinternals Suite" .zip file [direct], and extract is somewhere like "C:\Program Files\Sysinternals". Many users will never use this, but it makes many useful Windows tools available when needed. (I use Process Explorer all the time.)

Here are some more essentials for more technical users/developers:

Monday, January 28, 2008

Use JScript over VBScript

When trying to complete a Windows-based script for any type of system administration - at work, volunteering at my church & school, or otherwise - I've always been a bit intrigued at why anyone would choose VBScript over JScript.

While some of Microsoft's own examples are written in both VBScript and JScript, many are written exclusively in VBScript. I've not found any documentation that shows that VBScript is supported any better by - or has better support for - the Windows Script Host than JScript.

I finally happened to run across a great article that summarizes why JScript should be preferred, and lists many of the same reasons why I always convert any WSH scripts I'm involved in to JScript. The article is Eight Reasons Windows Administrators Should Learn JScript Instead of VBScript by Bill Stewart, on O'Reilly WindowsDevCenter.com.

Stewart's key points, followed by some of my highlights:

  1. JScript Is More Widely Used
    • JScript is really the same as JavaScript 1.5, while VBScript is proprietary to Microsoft.
  2. JScript Is Alive and Well
  3. JScript Is Easy to Learn
  4. JScript Is Object-Oriented
    • JScript shares many of JavaScript's powerful advantages and syntax. For example, many of the tips in my previous post on JavaScript Closures apply equally to JScript, but are impossible to match in VBScript.
  5. JScript's Regular Expression Handling Is Better
  6. JScript Arrays Are Much More Powerful
  7. JScript Date Handling Avoids Local Time Problems
  8. JScript Has Better Exception Handling
    • By comparison, exception handling is practically non-existent in VBScript.

In my opinion, many of these same points should also lead anyone to choose C# over Visual Basic .NET (VB.NET) when working with the Microsoft .NET framework.

Thursday, January 17, 2008

No 64-bit Windows for Dell

In my ongoing search for a new laptop, my current thought is to purchase the latest Dell Latitude, a D830. I was quite pleased with my previous Latitude C810, and the D830 seems to meet all my current requirements. My one outstanding concern is Dell's apparent policy to stick away from 64-bit Windows, either XP or Vista.

The only real disadvantages to running a 64-bit version of Windows are finding appropriate drivers, and possible incompatibilities with older software. A MSDN blogger recently describes installing 64-bit Vista on a Dell Latitude D830 without any noted issues: "I thought this would be painful and full of compromises but so far, my experience has been good." The advantages include being able to efficiently use all available RAM, up to 4GB and above.

The problem is that it seems Dell simply doesn't support the 64-bit versions on anything other than their Precision line of laptops. Configuring an M6300 to be roughly equivalent to a D830 seems to involve at least $1,000 added to the price tag, without any real advances in features or functionality.

Hewlett-Packard doesn't seem to have a problem here. Several of HP's Pavilion and Compaq notebooks are offered with either 32- or 64-bit Windows Vista preinstalled.

My biggest complaint is that I'd consider buying a notebook without any operating software or other software preinstalled. I could either put Linux on it, transfer over my existing Windows XP, or if I so decided, buy my desired version of Vista. However, Dell requires all of their computers to be shipped with an operating system preinstalled, and on this model, it must be Windows, and not a 64-bit version.

If I'm going to be forced to purchase a version of Windows with a new laptop, it should be the version I want, and the version that fully supports the hardware I'm purchasing.

Additionally, if a copy of 32-bit Vista were purchased through retail, Microsoft provides an option to upgrade to 64-bit for only a minimal processing fee. Additionally, if the Ultimate edition is purchased, the box already includes both 32-bit and 64-bit versions. Unfortunately, this upgrade path is not honored for OEM distributions, such as those installed by Dell.

I'm not the only one facing this dilemma, as a quick search reveals many others having the same issue with Dell. A few selections:

Update (2008-11-04):

Though there still appear to many of the same related issues with purchasing a 64-bit version of Windows Vista in Dell's online ordering, the situation appears to be improving. I just purchased a Dell Latitude E6500. It does offer 64-bit Vista, but only in the Business edition. However, according to this thread on Dell's forums, the 64-bit versions can be obtained by contacting Dell Support. If there are any issues, have the sales representative refer to "DSN Document ID: 158098 (Operating System Changes and Operating System Swaps - Dell Global Policy)", 5th bullet under policy, 1st sub-bullet.

Wednesday, November 7, 2007

Leave "My Documents" Alone!

Attention all software developers (particularly those in larger corporations selling end-user software for Windows):

"My Documents". Note the name. "My", as in mine - leave it alone!

If you're running any version of Windows, you probably have a My Documents folder. This was a great idea - a place for the user to keep user files, separate from the system and program files that can be easily restored or reinstalled.

Unfortunately, the rest of the software industry seems to be thinking that this is their folder as well, and that they put whatever they want in there. At the moment, I've got "Adobe", "eFax Messenger", "My Albums", "My Labels", "My Music", "My Pictures", "My Received Files", "My Scans", "My Videos", and "My Web Sites" - none of which I've created, nor do I really want!

Don't dictate my file organization for me. I, for one, don't want to store all my photos and/or videos in the same place. I may have different "photo" folders under other subfolders of "My Documents", grouped by categories, events, or otherwise.

If an application is going to store user data, either store it appropriately under "Application Data", or prompt the user where to save it.

Thursday, September 6, 2007

Windows Shadow Copy (VSS) Woes

Motive:

For a while, I've been meaning to work on a better backup solution to work under Windows. I've not yet seen a tool that is reliable, extensible, and able to copy in-use files. NTBackup, which comes with Windows, has the advantage of using Microsoft's Shadow Copy, which allows for backing up from a "snapshot in time", and also allows for copies of in-use files, but otherwise falls short of the goal.

Be warned - if you're reading this post this looking for a solution, there really is none. At current, this post only outlines some of the problems. If you have a suggestion, please leave a note!

Looking for Shadow Copy:

One of the first interesting pages I found was Adi Oltean's "The VSS (Volume Shadow Copy) SDK is available for download". It contains a "sample application" called VSHADOW. Though I don't like relying on a non-supported "sample", it looked somewhat promising. Sure enough, running "vshadow -wait d:" results in a shadow copy accessible by a special Windows device name while the command remains active, e.g. "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1". (It waits with a "Press <ENTER> to continue..." prompt.) There are features to access such a shadow copy by a drive letter or a mount point, but unfortunately, only under Windows Server 2003 (and presumably, Windows Vista). The vshadow readme.doc included with the SDK states that these special device names have "a special volume device syntax that is not compatible with certain shell commands ... Still, many Win32 applications or shell commands can operate on this device..." Using the copy command does work to copy files from the shadow copy, but even something as simple as getting a directory listing seems to require a bit of scripting.

In a moment of possible insanity, I thought it would be cool if I could access the shadow copy using the File class in Java. Since Java does rely on the underlying operating system APIs for OS-specific operations such as working with files, I wouldn't have been surprised if it had worked. Unfortunately, any attempts fail as if the files don't exist.

No help from Microsoft.Net:

Well, with no honest expectation for Java to interface with such advanced Windows features, I thought I'd try Microsoft's approach, Visual Studio 2005. Attempt:

DirectoryInfo di = new DirectoryInfo(
  @"\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1");

The result? A very discouraging exception:

System.ArgumentException was unhandled
  Message="Paths that begin with \\\\?\\GlobalRoot are internal
    to the kernel and should not be opened by managed applications."
  Source="mscorlib"
  StackTrace:
       at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)
       at System.IO.Path.GetFullPathInternal(String path)
       at System.IO.DirectoryInfo..ctor(String path)
       …

All I can say is, for as hard as Microsoft is pushing the .Net framework, such artificial limitations are very disappointing.

Someone else with the same goal:

One promising article I found was Craig Andera's "HoboCopy". I can't agree more with his two reasons for being unhappy with using ntbackup as a backup strategy, including its proprietary format. I also strongly agree with his following paragraphs which explain some of the advantages and strengths of the Volume Shadow Service (VSS) / shadow copy.

Unfortunately, it appears that Craig, too, discovered that working with VSS from managed code / .Net is severely broken / impossible. He continued with the challenge to write a tool using unmanaged C++. Unfortunately, not even HoboCopy meets my design requirement for a tool to interface with VSS.

Other approaches / notes:

Another promising approach I found was another blog entry by Adi Oltean, "A bit of black magic: How to assign drive letters to VSS shadow copies... on Windows XP !" Unfortunately, it relies upon an unsupported and nearly-impossible-to-find tool from various Microsoft resource kits, DOSDEV.EXE. (I did manage to find it in Microsoft Product Support's Reporting Tools. It is in the MPSRPT_SETUPPerf.EXE download.)

One last blog entry I found which was worth noting is Alex Thissen's "Volume Shadow Copy: your way to copying locked file".

Wish for the future:

My wish list doesn't seem that long for a tool or easy-to-use API:

  • Ability to copy files from a shadow copy, either through use of a file OR by stdout / application streaming.
  • Ability to retrieve directory listings and other basic file information such as size and last modified dates.
  • Ability to be used from managed code, e.g. C#.Net.