What's in Microsoft.VisualBasic for C# Developers: Part 7 - File System
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
The FileSystem class is what originally brought me to explorer this assembly because there is some very interesting options in the class which aren’t available elsewhere. To add to confusion there is two FileSystem’s in the Microsoft.VisualBasic namespace :
- Microsoft.VisualBasic.FileSystem
- Microsoft.VisualBasic.FileIO.FileSystem
The one I am interested in, and this post covers, is the second one which has some fantastic options: unfortunately there is way more functions in there than a single blog post can cover (27 methods not counting overloads), so I am going to focus on just two of them which bring new features, i.e. not just wrapping some other .NET API.
DeleteDirectory
The first I want to look at is the DeleteDirectory method which allows you to easily delete a directory. What makes this fantastic is that it can empty the directory of files first (i.e. it handles non-empty directories). Second it supports deleting to the recycle bin and finally it supports a nice pretty UI for the deletion action, including confirm dialog and progress bar dialog.
string testFolder = FileSystem.CombinePath(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"Demo"); FileSystem.CreateDirectory(testFolder); FileSystem.DeleteDirectory(testFolder, UIOption.AllDialogs, RecycleOption.SendToRecycleBin, UICancelOption.ThrowException);
In the code above uses a few options from FileSystem.
- CombinePath – this is provides a error checked and normalised concatted path using System.IO.Path.CombinePath.
- CreateDirectory – this does some error checking and wraps System.IO.Directory.CreateDirectory.
- DeleteDirectory – This is what we are talking about with the display of UI and send to recycle bin enabled.
There is similar methods to DeleteDirectory, such as MoveDirectory & CopyDirectory and similar items for files: CopyFile, MoveFile etc…
FindInFiles
This is a very useful function which allows you to search files on your machine for specific content (i.e. search in the file, not just the filename). This is not wrapping any functionality behind the scenes (for a change):
string myDocs =Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var result = FileSystem.FindInFiles(myDocs, "MVP", true, SearchOption.SearchTopLevelOnly); MessageBox.Show(result.Aggregate((c, n) => { return c + Environment.NewLine + n; }));
The above code shows me searching the My Documents folder for any file with the letters MVP (in any case – controlled by the third parameter). It can be filtered using standard wildcards and and search sub-directories too
What's in Microsoft.VisualBasic for C# Developers: Part 6 - Networks
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
The Network class is an interesting set of wrappers around other classes in .NET which is useful for simplification of certain actions:
- DownloadFile & UploadFile
- Ping
- IsAvailable
DownloadFile & UploadFile
These two methods are interesting in that the wrap the WebClient class which make it much easier to use while still giving a lot of flexibility. This isn’t the most robust way to work with the HTTP (download) & FTP (upload) but it is very useful. For example the easiest way to download a file:
Network network = new Network(); network.DownloadFile("http://www.bing.com", @"c:\bing-index.html");
It includes 10 overloads which the most complex is:
One of the interesting parameters I wanted to highlight is the showUI parameters which when set to true gives you a dialog ox with a progress bar and cancel support. It’s not pretty but, like a lot of this Network class it is functional:
Ping
Just like DownloadFile & UploadFile, Ping wraps other functions in the framework, namely the Ping class from System.Net.NetworkInformation. It really just takes two lines of code if you used the Ping class and makes it two lines using the Network class – not really that helpful:
Network network = new Network(); string message = network.Ping("www.bing.com") ? "Bing is up" : "Bing is down";
IsAvailable
The last in the Network Trilogy is the IsAvailable property which tells you if you are connected to a network. All it does is call: NetworkInterface.GetIsNetworkAvailable.
Why you want to write two lines for this when you could use the one line it uses is confusing, but it’s there:
Network network = new Network(); string message = network.IsAvailable ? "Network up" : "Network down"; // I prefer this: string message2 = NetworkInterface.GetIsNetworkAvailable() ? "Network up" : "Network down";
What's in Microsoft.VisualBasic for C# Developers: Part 5 - Hardware
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
Hardware isn’t just related to the computer information, like OS version and memory, but it also includes a variety of other types of devices such as audio, clocks, keyboards and many more. The VisualBasic library provides us with access to a lot of these pieces of hardware:
Audio
Microsoft.VisualBasic.Devices.Audio is a interesting class which allows us to play various sounds it has three functions that are key:
- Play – This allows us to play a wave file, either by passing in the file name, a stream or byte array. There are a few overloads to allow you to control how the audio is played.
- Stop – Stop the playing audio.
- PlaySystemSound – This plays the sound associated with a specified system event.
string waveFile = @"C:\Windows\winsxs\amd64_microsoft-windows-speech-userexperience_31bf3856ad364e35_6.1.7600.16385_none_77fee1b2657da663\Speech Sleep.wav"; Audio audio = new Audio(); // play full file to wnd audio.Play(waveFile, Microsoft.VisualBasic.AudioPlayMode.WaitToComplete); // play first 300ms and stop audio.Play(waveFile); Thread.Sleep(300); audio.Stop(); // play sound associated with a question audio.PlaySystemSound(System.Media.SystemSounds.Question); Console.ReadKey();
Clock
Microsoft.VisualBasic.Devices.Clock is rather pointless it has three properties which match to existing properties we know and love.
- GmtTime equals DateTime.UtcNow
- LocalTime equals DateTime.Now
- TickCount equals Environment.TickCount
Keyboard
This provides us with an interesting mixed bag first we have 3 Boolean properties, one for each modifier key (Ctrl, Alt & Shift) which tell us if it is being pressed. Next we have 3 Boolean properties, one for each of the toggle keys (Caps lock, scroll lock & num lock) which tells you if they are enabled.
Keyboard keyboard = new Keyboard(); Console.WriteLine("Alt pressed: {0}", keyboard.AltKeyDown); Console.WriteLine("Ctrl pressed: {0}", keyboard.CtrlKeyDown); Console.WriteLine("Shift pressed: {0}", keyboard.ShiftKeyDown); Console.WriteLine("Caps on: {0}", keyboard.CapsLock); Console.WriteLine("Numlock on: {0}", keyboard.NumLock); Console.WriteLine("Scroll lock on: {0}", keyboard.ScrollLock);
However the interesting piece of code is the SendKeys method which actually allows you to send key strokes to the active window, basically to simulate a user typing.
There is one thing to be aware of and that is if you are using something which does not handle window messages for example a console application. In this case you must use the overload which takes a boolean as a second parameter and set this to true.
// winforms keyboard.SendKeys("Hello world!"); // console keyboard.SendKeys("Hello world!", true);
Mouse
Microsoft.VisualBasic.Devices.Mouse does not let you control Mouse from the Matrix, it merely provides status information to you on the hardware mouse you are using via three properties:
- ButtonsSwapped – Are the left and right mouse buttons swapped?
- WheelExists – Does the mouse have a mouse wheel?
- WheelScrollLines – How many lines does a single notch of the mouse wheel to scroll?
Ports
Need to work with serial (COM) ports? The Microsoft.VisualBasic.Devices.Ports provides you with a simple way to do that, however nothing it provides you do not already get from System.IO.Ports.SerialPort except saving a few lines of code.
The OpenSerialPort method does the following:
- Creates a new System.IO.Ports.SerialPort – OpenSerialPort does contain overloads which match to the constructors for SerialPort.
- It then calls Open on the port.
- It returns the port.
That three lines of code wrapped into one for you.
The other item provided on Ports is the SerialPortNames property which returns a ReadOnlyCollection<String> of the names of the port. It does this by calling the GetPortNames method from SerialPort, which returns an array and then converts that result to the collection. The only time you should use this is if you really need a ReadOnlyCollection<String> as calling the GetPortNames method directly and working with the array is much faster.
What's in Microsoft.VisualBasic for C# Developers: Part 4 - Computer Info
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
For today we will be looking at a very useful class ComputerInfo, which provides a small set of information on the computer. It doesn’t provide a lot of info but the information it provides are key:
- OSFullName: The “nice” name for the OS – like Windows 7 Ultimate
- OSVersion: The OS version number
- OSPlatform: The OS platform
- TotalPhysicalMemory, AvailablePhysicalMemory, TotalVirtualMemory, AvailableVirtualMemory: Memory usage information
- InstalledUICulture: The culture that was used during the install, this is the exact same as System.Globalization.CultureInfo.InstalledUICulture
ComputerInfo info = new ComputerInfo(); Console.WriteLine("You are running {0} ({1})", info.OSFullName, info.OSVersion); Console.WriteLine("\t this is built on the {0} platform.", info.OSPlatform); UInt64 usedPhysical = info.TotalPhysicalMemory - info.AvailablePhysicalMemory; UInt64 usedVirtual = info.TotalVirtualMemory - info.AvailableVirtualMemory; Console.WriteLine("Memory Information in Mb (Available | Used | Total)"); Console.WriteLine("\t Virtual: {0} | {1} | {2}", info.AvailableVirtualMemory / 1048576, usedVirtual / 1048576, info.TotalVirtualMemory / 1048576); Console.WriteLine("\t Physical: {0} | {1} | {2}", info.AvailablePhysicalMemory / 1048576, usedPhysical / 1048576, info.TotalPhysicalMemory / 1048576); Console.WriteLine("You are running the following culture {0}", CultureInfo.CurrentCulture.EnglishName); if (CultureInfo.CurrentCulture != info.InstalledUICulture) { Console.WriteLine("BUT you installed with {0}", info.InstalledUICulture.EnglishName); } else { Console.WriteLine("and you installed with that culture too"); }
This gives us:
This is isn’t the only way to get computer information, there is plenty in other locations in the framework – for example the System.Environment class from the mscorlib assembly has things like:
- Environment.Is64BitOperatingSystem
- Environment.Is64BitProcess
- Environment.MachineName
- Environment.OSVersion
- Environment.ProcessorCount
- Environment.Version
What's in Microsoft.VisualBasic for C# Developers: Part 3 - Financial
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
Yesterday’s post covered some interesting, yet very simple features in Microsoft.VisualBasic so today I thought I would cover some more complex code: Financial.
This is a class with 13 static method who all return a Double, and if financial code wasn’t complex to begin with the method names are as cryptic as you can get. I’ve broken them into three groups: cash flow, general, depreciation and annuity based.
Cash Flow
These calculations look at investments and cash flows:
- IRR: Provides the internal rate of return for a series of periodic cash flows.
- MIRR: Provides the modified internal rate of return for a series of periodic cash flows.
- NPV: Provides the net present value of an investment.
Example of using the above methods:
// need to place to store profit/loss // must have atleast one negative and one postive value in it IList<double> values = new List<double>(); values.Add(-100000); // startup costs - cost money to make money values.Add(10000); // income in first year values.Add(15000); // income in second year values.Add(17500); // income in third year values.Add(75000); // income in forth year - got govt. contract that year ;) double[] valuesArray = values.ToArray(); double loanRateGuess = 0.1; // start guessing loan at 10% double rateIRR = Financial.IRR(ref valuesArray, loanRateGuess) * 100; double reinvestmentRate = 0.12; // MIRR also includes the reinvestment rate 12% double rateMIRR = Financial.MIRR(ref valuesArray, loanRateGuess, reinvestmentRate) * 100; // working out net present value needs a fixed rate double fixedRate = 0.08; // 8% double netPresentValue = Financial.NPV(fixedRate, ref valuesArray); Console.WriteLine("Net present value: {0:0.00}", netPresentValue); Console.WriteLine("Rate of return is:"); Console.WriteLine("\t{0:0.00}% (Calculated using IRR)", rateIRR); Console.WriteLine("\t{0:0.00}% (Calculated using MIRR)", rateMIRR);
Gives us:
Depreciation
I understand depreciation as: how much value an item loses over time.
- DDB: Allows you to work out depreciation using the double-declining balance method (DDB) or a custom method. The DDB calculation per period is: Depreciation / Period = ((Cost – Salvage) * Factor) / Life
- SLN: Provides a value specifying the straight-line depreciation of an asset for a single period. SLN is calculated using:(Cost - Salvage) / Life
- SYD: Provides a value specifying the sum-of-years digits depreciation of an asset for a specified period. This is similar to DDB but calculated differently.
Example of using all the above methods to figure out how much you lose on an iPhone over two years:
double iPhoneInitialCost = 10000; double iPhoneResale = 3500; double YearsUntilNextUpdate = 2; // work out deprecation per year double deprectionPerYear = Financial.SLN(iPhoneInitialCost, iPhoneResale, YearsUntilNextUpdate); double sydValue = iPhoneInitialCost; double ddbValue = iPhoneInitialCost; for (int year = 1; year < YearsUntilNextUpdate + 1; year++) { double syd = Financial.SYD(iPhoneInitialCost, iPhoneResale, YearsUntilNextUpdate, year); double ddb = Financial.DDB(iPhoneInitialCost, iPhoneResale, YearsUntilNextUpdate, year); sydValue -= syd; ddbValue -= ddb; Console.WriteLine("In year {0} you will lose", year); Console.WriteLine("\t {0:0.00} (Calculated using SYD)", syd); Console.WriteLine("\t {0:0.00} (Calculated using DDB)", ddb); Console.WriteLine("Phone value"); Console.WriteLine("\t {0:0.00} (Calculated using SYD)", sydValue); Console.WriteLine("\t {0:0.00} (Calculated using DDB)", ddbValue); Console.WriteLine(); }
Which gives us the painful realisation of how quick value is lost:
Annuity Based
An annuity is a series of fixed cash payments made over time. An annuity can be a loan (such as a home mortgage) or an investment (such as a monthly savings plan).
If you are working out annuities there is a number of calculations around those:
- If you have the payment, period and interest you can work out the future value using FV over a period.
- If you have the future value, payment and period you can work out the interest using IPmt over a period.
- If you have the future value, payment, and interest you can work out the period using NPer over a period.
- If you have the future value, period and interest you can work out the payment using Pmtt over a period.
Other methods around annuities:
- PPmt: Calculate the principal payment of an annuity.
- PV: Calculate the present value of an annuity.
- Rate: the interest rate per period for an annuity calculated by iteration.
Example of using FV to work out savings:
double monthlySavings = 1000; double interestRate = 8; double yearsYouWillSave = 10; double deposit = 0; // specifies if you save at start or end of month DueDate dueDate = DueDate.EndOfPeriod; if (interestRate > 1) { // must be expressed as a percentage interestRate = interestRate / 100; } // converted to interested per month interestRate = interestRate / 12; // figure out how many months that is double months = yearsYouWillSave * 12; // note savings and deposit are converted to negative as we are saving // if we were paying off they would be positives double savings = Financial.FV(interestRate, months, -monthlySavings, -deposit, dueDate); Console.WriteLine("In {0} years, you will have saved: {1:0.00}", yearsYouWillSave, savings);
gives us:
What's in Microsoft.VisualBasic for C# Developers: Part 2 - Constants & Control Characters
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
We will start off the series with something very simple, two classes which give us access to some constant definitions that may be useful to use.
Control Characters
Microsoft.VisualBasic.ControlChars contains 10 constant fields for commonly used items:
public const char Back = '\b'; public const char Cr = '\r'; public const string CrLf = "\r\n"; public const char FormFeed = '\f'; public const char Lf = '\n'; public const string NewLine = "\r\n"; public const char NullChar = '\0'; public const char Quote = '"'; public const char Tab = '\t'; public const char VerticalTab = '\v';
As you can see this is just a useful list to have and can make code much easier to read.
As a C# developer there is one on that list I wouldn’t use – NewLine. In the mscorlib assembly, there is an Environment class which contains a property called NewLine which, on my machine is the exact same as the one above. So why would I use that over the VB one? This is because Environment.NewLine changes based on underlying OS – so on systems which use just \n it will be that where the VB one is always the same regardless of what the OS uses.
Constants
Microsoft.VisualBasic.Constants contains a lot of constant definitions which are used through out the whole Microsoft.VisualBasic assembly. A lot are to be used with specific functions, for example vbAbort is meant to be used with the MsgBox function, but there are a few which are interesting:
Control Characters
The first interesting group is that almost all the Control Characters from Microsoft.VisualBasic.ControlChars are repeated here – the only one missing is Quote. So now you have two ways (or three ways for Newline) to get control characters.
public const string vbBack = "\b"; public const string vbCr = "\r"; public const string vbCrLf = "\r\n"; public const string vbFormFeed = "\f"; public const string vbLf = "\n"; public const string vbNewLine = "\r\n"; public const string vbNullChar = "\0"; public const string vbTab = "\t"; public const string vbVerticalTab = "\v"
Tristate
Developers often have an bad habit of thinking that they can build it better than other people have done so in the past. There is a famous example of someone who decided that a boolean (something that is either true or false), needed a third option – FileNotFound.
It appears the VB guys also decided this would be a good route to go too, so we have the Tristate enum, which is atleast a little more logical than the above example.
public enum TriState { False = 0, True = -1, UseDefault = -2 }
The values here match to the Convert.ToBoolean(int value) method where 0 is always false and anything else is true.
With the .NET Framework 4, I suspect this is not that useful anymore as you can set the default value on the parameters of a method (see example below), but if you are on older versions then this may be useful.
private void Demo(bool value = true)
Finally an AWESOME competition for South African Developers
I often find too many competitions from Microsoft ignore the southern tip of Africa or focus on specific markets, like education with the great ImagineCup event. Finally us hard working developers get a great competition: Internet Explorer 9 Top Developer Competition!
This competition wants* developers to either create an awesome IE 9 add-on or light up a web site with some of the new awesome IE 9 features – so if you a web dev, html monkey, C++ or .NET developer you can take part!
The prize? A trip to PDC – the conference were two years ago everyone got hand build super laptops and last year Windows Phone 7 devices**, not to mention it is where the top Microsoft development speakers meet!
So get coding, you only have until March!!
Some things you may want to check out:
- Competition website: www.6to9.co.za
- IE 9 Features: http://www.6to9league.co.za/features.aspx
- IE 9 HTML 5 Test Drive Site: http://ie.microsoft.com/testdrive/
- SpicIE, a plug in creation framework for IE: http://code.msdn.microsoft.com/SpicIE
- IE Addon’s website (for inspiration): http://www.ieaddons.com/en/
- Firefox Addon’s website (for inspiration ): https://addons.mozilla.org/
* Side note: “The competition wants” really sounds like the competition is a living entity and will punish you if you don’t do this… it isn’t and it won’t.
** My guess for this year at PDC is giving everyone tablets - just looking at what was announced at CES.
What's in Microsoft.VisualBasic for C# Developers: Part 1 - An Introduction
[This blog is part of a larger series, to find more parts in the series please see the Series Index]
The .NET Framework is a large and complex system supporting many languages and when I do battle with the gods of code, my weapon of choice is C#.
When you create a C# project you get a reference to Microsoft.CSharp added and if you ever looked in there it is really sparse – just two classes:
As all other languages have a similar assembly, and maybe you had the same monkey thought I did “Those are just some low level stuff for the language, nothing I want.”
I was wrong, again. Maybe the C# doesn’t have much, but the Microsoft.VisualBasic is not just low level plumbing but includes an monolith full of goodness!
WHOA THERE!
You may be asking how can C# developers use an assembly written in VB.NET? The answer is: very easily
All assemblies are actually IL (intermediate language) which means that no matter what language a .NET assembly is developed in, you can use it in the language of your choice.
This blog series will cover some of the goodness is available in this assembly and hopefully at the end, you will be a better, faster and more productive C# developer thanks to VB.NET!
Presentation Dump: End of 2010
Previous presentation dumps:
All slides can be found at: http://www.slideshare.net/rmaclean
This is the smallest presentation dump so far, mostly because a lot of the work I did in the second half of 2010 was at public events, like Tech-Ed, and those have already been upload. One of the big pushes I did in the last part of the year was around design of the presentation and I think the T4 presentation is a highlight of that work for me.
T4 Templates
OData
Developing RESTful Services in .NET
Workflow Foundation 4
What's in Microsoft.VisualBasic for C# Developers: Series Index
This page lists all the parts of the series, if a part is not hyper-linked it means that it will come up in the near future and you should subscribe to the RSS feed to get notified when it arrives.
This list is subject to change as I write posts.