On my home network, I have a media file server running Vista 64-bit that serves out music and movies. Since everything is behind a router, I decided to make the shared media folders accessible to anyone on my home network. All you have to do is browse to the media server and start accessing content, without having to log in.
To enable anonymous browsing of a shared folder that is shared by a Vista PC (that is not on a domain), do the following:
Enable the Guest Account:
Run "lusrmgr.msc", select the Users folder.
Right click on the Guest user and choose Properttes.
Uncheck "Account is disabled".
Enable "Public folder sharing" and disable "Password protected sharing":
Choose Start, right click on Network, and choose Properties.
Enable "Public folder sharing".
Disable "Password protected sharing".
For each shared folder:
Grant Everyone Read permission to the Share.
Grant Everyone Read and Execute (NTFS) permission on the shared folder itself.
Against popular wisdom, I decided to upgrade my bedroom home theater PC to Vista 64-bit a couple days ago (just have to make full use of all of my precious 4GB of RAM). Everything is working surprising well so far, with the exception of sound! Whenever I play any audio, my speakers now produce all kinds of pops and crackles along with the normal audio stream. Urgg.
After a couple of days of googling, tweeking various sound settings, uninstalling/reinstalling drivers, etc. without success, I almost gave up on the thing. Then I decided to try just one more thing, changing the default sample rate to “2 channel, 16 bit, 44100 Hz (CD Quality)” from the default “2 channel, 24 bit, 48000Hz” and just like magic, the pops and crackles are gone.
If you do any web scraping (also known as web data mining, extracting, harvesting), you are probably familiar with the main steps: navigate to page, retrieve HTML, parse HTML, extract desired elements, repeat. I’ve found the SgmlReader library to be very useful for this purpose. SmglReader turns your HTML into XML. Once you have the XML, it’s fairly easy to use built-in classes such as XmlDocument, XmlTextReader, XPathNavigator to parse and extract the data you want.
Now to the labor intensive part: before your program can make sense of the XML, you have to manually analyze the HTML/XML first. Your program won’t know jack about how to extract that stock price until you tell it exactly where the stock price is, typically in the form of an XPath expression. My process of getting that XPath expression goes something like this:
Scroll to/find desired element in the XML editor.
Does element have unique attributes that can be used?
a – If yes, code XPATH statement with filter on attribute value. Example: //Table[@id=”searchResultTable”].
b – If no, code an absolute XPATH expression. Example: /html/body/div/pre/font/table/tr/td/table/tr/td/span.
Step 2b is where it gets very labor intensive and boring, especially for a big web page with many levels of nesting. Visual Studio 2005 XML Editor/Resharper have a couple of features that I find useful for this:
– Visual Studio’s Format Document (Edit/Advanced/Format Document) command formats the XML with nice indentation and makes it a lot easier to look at.
– With Resharper, you can press Ctrl-[ to go to the start of the current element, or if you are already at the start, go to the parent element.
Even with the above tools, it’s still a painful and error-prone exercise. Luckily for us, Firebug has the perfect feature for this: Copy XPath. To use it, open your HTML/XML document, open the Firebug pane (Tools/Firebug/Open Firebug), navigate to the desired element, right click on it and choose “Copy XPath”.
You should now have this XPath expression in the clipboard, ready to be pasted into your web scrapper application: “/html/body/div/table/tr/td/table”.
A feature that I would love to have is the ability to generate an alternate XPath expression using “id” predicates, such as this: “//Table[@id=”searchResultTable”]”. With web pages that are not under your control, you want to minimize the chance that changes on the pages impact your code. Absolute XPath expressions are vulnerable to any kind of changes on the page that change the order and/or nesting of elements. On the other hand, XPath expressions using an “id” predicate are less likely to be impacted by layout changes because in HTML, element IDs are supposed to be unique. No matter where your element is on the page, if it has the same ID, you should still be able to get to it by looking up the ID. Hmm… this sounds like a good idea for a Visual Studio Add-in.
Just in case anyone else needs to do this out there…
I recently got myself a nice ThinkPad X60 Tablet PC. It doesn’t come with a DVD-Drive and although I have an external DVD drive, I just can’t seem to find its power adapter. Argg!
In order to do this, you must have the following:
Windows XP installed on the PC you want to install Vista to.
Log in into Windows XP on the PC you want to install Vista to.
Use Partition Magic or another partitioning tool and create a second partition for Vista. Make it a Primary Partition (don’t know if this is required but this is what I did). Format the second partition with NTFS. Your Windows XP installation will be left alone and you will be able to dual boot to it.
Create a folder (let’s called it "c:\VistaInstall") and copy all files from the Vista DVD / ISO there (either extract the files from an ISO image using a Virtual CD/DVD emulator like Daemon Tools, or copy the files from another PC with a DVD drive over the network).
Run Setup.exe from c:\VistaInstall.
Choose Custom Install and follow the prompts to select the second partition you created.
Follow the rest of the on-screen instructions.
As part of the installation, Vista Setup will copy the installation files to the new partition. After it reboots, it’ll have all the files there to continue.
After you are done with the install, you can delete the temporary folder c:\VistaInstall that you created.
Use Powershell array expression syntax @(…) allows you to force a scalar return value to be wrapped in a array, if it’s not already in an array. I learned about this the hard way while trying to figure out while Get-Childitem sometimes returns an array and sometimes a scalar. Bruce Payette wrote more about it here.
Windows Mobile / Pocket PC
I needed a way to stream music and other media to my Windows Mobile phone (Samsung SCH-i760) and all the PCs around the house. Orb seems to be the answer. I’ve only had it running for a few days but it seems to be working great. I can stream music and photos (have not tested videos yet) to any PC in the house or anywhere on the net. I can also listen to my entire music library on my i760 phone anytime, anywhere through Verizon Wireless’s unlimited (with a catch… not to exceed 5GB) EDVO connection.
I am a Google Mobile guy, but Yahoo! Go for Windows Mobile also looks very cool. I downloaded it to my Samsung SCH-i760 a few days ago. I am still checking it out but here are a few things I like:
Nice and responsive interface.
Built-in RSS Reader.
Street and satellite maps.
Here are a few screenshots:
Software and Tools
You can configure Notepad++ to always use spaces for tabs/indentation. The option is a little hidden. It’s in Settings/Preferences/MISC, under Tab Setting:
With the above code, anytime the order of columns in the SQL statement or stored procedure changes, the code is broken. And if you have lots of columns to read from, it’s a real nightmare to maintain the indexes.
The next time you write another DataReader loop, consider doing it this way instead:
using (IDataReader dr = cmd.ExecuteNonQuery())
int ORDER_ID = dr.GetOrdinal("OrderID");
int CUSTOMER_ID = dr.GetOrdinal("CustomerID");
int EMPLOYEE_ID = dr.GetOrdinal("EmployeeID");
int ORDER_DATE = dr.GetOrdinal("OrderDate");
int FREIGHT = dr.GetDecimal("Freight");
int orderId = dr.GetInt32(ORDER_ID);
string customerId = dr.GetString(CUSTOMER_ID);
int employeeId = dr.GetInt32(EMPLOYEE_ID);
DateTime orderDate = dr.GetDateTime(ORDER_DATE);
double freight = dr.GetDouble(FREIGHT);
// do stuff
Using GetOrdinal makes the code much more readable and maintainable. You are calling GetOrdinal just once for each column, any performance penalty is insignificant compared to the benefits. Be careful not to put the GetOrdinal code inside the while block as that will unnecessarily slow you down (about 3% according to this article).
I think this is useful and not well known enough to warrant its own blog post.
Did you know that there is a Visual Studio command called File.OpenContainingFolder? Asmita A Wankhede wrote about it, but he left a few important details out.
By default, this command does not have a shortcut, so you would have to assign one to it (try CTRL+SHIFT+ALT+O). Also, the "item" that this command works on is the currently opened item in the editor, not the selected item in the Solution Explorer. See my Visual Studio tips article for instructions on how to create new shortcuts (section 3 – Make New Shortcuts).
I can’t believe I didn’t know about this Visual Studio command before: File.OpenContainingFolder. Asmita A Wankhede mentioned it, but he left a few important details out. By default, this command does not have a shortcut, so you would have to assign one to it (try CTRL+SHIFT+ALT+O). Also, the "item" that this command works on is the currently opened item in the editor, not the selected item in the Solution Explorer. See my Visual Studio tips article for instructions on how to create new shortcuts (section 3 – Make New Shortcuts).
Aaron Lerch shared a tip on how to use Powershell to perform search-and-replace on an entire folder hierarchy.
If like me, you have heard about SubSonic but don’t know much about it, Kent Sharkey’s Introduction to SubSonic (Dotnetslackers) provides a quick primer.
Software And Tools
Did you know that something called Robocopy (short for Robust File Copy, not Robot Copy), is the new XCOPY? It’s a standard tool in Windows Vista and is also available as part of the Windows Resource Kit. Via Don Box’s Spoutlet on Pluralsight.
I recently tried and liked GhostDoc very much. It’s a free Visual Studio add-in to help write XML documentation comments. Roland Weigelt wrote a nice intro article on GhostDoc on DotnetSlackers here.
SyncBackSE is a great folder synchronization utility. It has tons of features… maybe even a little bit on the bloated side. It costs $30 for a single license. If you just want something simple, Microsoft’s free SyncToy may do the trick for you.
From CES, it looks like Blu-ray will be the winner of the HD format war. No, the war is not completely over, but this was the landing at Normandy… so to speak. The loss is just too great for the HD-DVD camp to recover.
Did you know Microsoft Outlook has supported type-ahead since Outlook 2003?
I didn’t. I upgrade my home PC to Outlook 2007 a few days ago and was pleasantly surprised to find type-ahead working. I fired up the old copy of Outlook 2003 and type-ahead worked in that version too. I am pretty sure it didn’t work in versions prior to 2003.
Type-ahead is great for using with the Move to Folder or Copy to Folder features. If you use Outlook to get your Gmail via IMAP, you’ll appreciate the type-ahead feature since you need to move messages a lot.
To see type-ahead working, in the Move Items dialog box (with a message selected, press CTRL+SHIFT+V), type the first few letters of any folder name. The current folder selection will move to the folder that matches what you type.