Coding Faster with the dotNetTips Utility: November 2020 Update

My goal is to release quarterly updates to my NuGet packages and source code. This November 2020 update includes code I moved some code from my CLR open-source projects. It also includes over 28 new methods and types along with more unit testing and more benchmark tests. Below, I have documented some of the new methods along with a new type and some older methods too.

GitHub: https://github.com/RealDotNetDave/dotNetTips.Utility.Core/releases
NuGet: http://bit.ly/dotNetDaveNuGet

Calculating Total Size of Files in a Directory

The DirectoryInfo type in .NET does not have a method to return the total size of the files underneath that directory, so I added an extension method called GetSize(). I need this for some upcoming changes I need to do to my free app for .NET developers. Here is how to use it.

var directory = new DirectoryInfo(Environment.GetFolderPath(
                                  Environment.SpecialFolder.Cookies));

var result = directory.GetSize(searchPattern: "*.cookie",
                               searchOPtion: SearchOption.AllDirectories);

Checking that the User is an Administrator

In my free app for software engineers, I check to see if the user is running the app using admin rights, I use App.IsUserAdministrator(). In this app, I warn the user that the app will work better running under admin rights. Here is how I do that in the app.

if (App.IsUserAdministrator() == false)
{
    this.WriteUserMessage(new DevMessage { Message =
                          Resources.UserMessageCouldNotRunAsAdmin,
                          Type = MessageType.Important });
}

Checking to See if the Current Process is Already Running

Since C# apps do not have an easy way to prevent two instances of the same app from running (like VB.NET projects do) I needed that check for my free app for software engineers. So I use App.IsRunning(). In my app, if the app is already running, I just shut down the app that is loading by using App.Kill().

Based on my benchmark testing, App.IsRunning() has a performance mean of 377,618.047 ns.

Checking to See if a Process is Running

In my free app for software engineers, when the app starts, I check to see if Visual Studio is running and if it is, I warn the user that they should close it before using the app. I use the App.IsProcessRunning() method as shown below.

App.IsProcessRunning("devenv");

Based on my benchmark testing, this method has a performance mean of 220,639.168 ns.

Copying a File Asynchronously

The File type in .NET does not support any async methods.  So, I created FileHelper.CopyFileAysnc() that uses the async methods from FileStream. Here is an example on how to use it.

var result = await FileHelper.CopyFileAsync(file: fileToCopy,
                              destinationFolder: this._tempPath)
                              .ConfigureAwait(true);

CopyFileAysnc() returns the file size as a long.

Downloading File from Web Asynchronously

If you need to download a file from the web asynchronously, then you can use FileHelper.DownloadFileFromWebAsysc() that will store it in a file location of your choice. Here is an example of how to use it.

var fileToDownload = @"https://dotnettips.com/dotnettips.png";

await FileHelper.DownloadFileFromWebAsync(new Uri(fileToDownload),
        Path.Combine(this._tempPath.FullName, "dotNetTips.Com.logo.png"));

Ensuring a Host is Available

One of the things I mention in my Defensive Programming book and conference session is to periodically check to ensure that a host, such as http://www.google.com, is available before sending a request. If the host is unavailable, it can cause exceptions in the application. This also allows you to disable buttons in the click such as “Send” until the host is available again. I have been coding like this since the very early days of .NET.

I created a method called NetworkHelper.IsHostAvailable() to ping the host. Here is an example on how you can use it to check Google.

var result = NetworkHelper.IsHostAvailable("www.google.com", timeout: 500);

var result = NetworkHelper.IsHostAvailable("8.8.4.4", timeout: 500);

In my unit test, using IsHostAvaialble() to check http://www.googe.com took around 70 milliseconds.

New String Extensions

Here are more string extensions that I’ve added in this release.

  • FromBase64(): Converts a Base64 string to string.
  • Extract(): Extracts a string from a beginning and end value.
  • ToTitleCase(): Converts a string to title case (capitalize the first letter of each word).
  • Parse<T>(): Parses a string to a type.
  • ToBase64(): Converts a string to a Base64 string.
  • ComputeHash(): Computes a hash from a string value. Formats supported are: HMAC, MACMD5, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512, MD5, SHA1, SHA256, SHA384 and SHA512. Based on my benchmark testing, using SHA256 with this method has a performance mean of 11,159.774 ns.

Retrieving Computer Information

For information that I use to log issues or information, I created a type called ComputerInfo() that returns common information. Here is just some of the information from my system.

ComputerCulture:eng,
ComputerUICulture:eng
FrameworkDescription:.NET Core 3.1.9
FrameworkVersion:{_Build:9,_Major:3,_Minor:1,_Revision:-1}
HasShutdownStarted:false,
IPAddress:123.456.7.8
Is64BitOperatingSystem:true
Is64BitProcess:true
IsUserInteractive:true
LogicalDrives:[C:\\]
MachineName:DESKTOP-ABCDEF,
OSDescription:Microsoft Windows 10.0.19041
OsMemoryPageSize:4096
PhysicalMemoryInUse:49057792
ProcessorCount:4,
SystemDirectory:C:\\WINDOWS\\system32,
UserDomainName:DESKTOP- AA2FHJ
UserName:david

Retrieving Environment Variables

The values in the Windows environment variables can be very useful to retrieve information about the user and system. You can use App.GetEnviromentVariables() to retrieve this information. Below is an example of just some of the data from my system.

USERPROFILE:C:\Users\david
USERNAME:david
CommonProgramFiles:C:\Program Files\Common Files
USERDOMAIN:DESKTOP-ABCDEF
PROCESSOR_REVISION:8e09
ProgramFiles(x86):C:\Program Files (x86)
VisualStudioEdition:Microsoft Visual Studio Enterprise 2019
SystemDrive:C:
VSLS_SESSION_KEEPALIVE_INTERVAL:0
SESSIONNAME:Console
USERDOMAIN_ROAMINGPROFILE:DESKTOP-C22DAVET
CommonProgramFiles(x86):C:\Program Files (x86)\Common Files
ALLUSERSPROFILE:C:\ProgramData
HOMEDRIVE:C:
COMPUTERNAME:DESKTOP-ABCDEF
PUBLIC:C:\Users\Public
VSAPPIDNAME:devenv.exe
ProgramFiles:C:\Program Files
PROCESSOR_ARCHITECTURE:AMD64
windir:C:\WINDOWS
NUMBER_OF_PROCESSORS:4
ProgramData:C:\ProgramData
TMP:C:\Users\david\AppData\Local\Temp
TEMP:C:\Users\david\AppData\Local\Temp
VisualStudioDir:C:\Users\david\Documents\Visual Studio 2019
HOMEPATH:\Users\david
OS:Windows_NT
LOCALAPPDATA:C:\Users\david\AppData\Local
APPDATA:C:\Users\david\AppData\Roaming
VisualStudioVersion:16.0
SystemRoot:C:\WINDOWS
PROCESSOR_IDENTIFIER:Intel64 Family 6 Model 142 Stepping 9, GenuineIntel

Retrieving the .NET Framework Description

When you are logging information when an exception is thrown, it might be useful to log the .NET Framework description that the app is running under. To do this, you can use App.FrameworkDescripion. Here is an example of the output.

.NET Core 3.1.9

Retrieving Application Executing Folder

If you need to retrieve the location of where the current executable is running from you can use App.ExecutingFolder(). This is an example of the result from my unit test project.

C:\\src\\GitHub\\dotNetTips.Utility.Core\\src\\Unit Tests\\dotNetTips.Utility.Standard.Tests\\bin\\Debug\\netcoreapp3.1

Retrieving Application Information

To easily retrieve common application information, you can use App.AppInfo(). It’s very simple to use.

var info = App.AppInfo;

Here is an example of the results from my unit tests.

DOTNETTIPS-NUGET-APPINFO

Retrieving & Changing Culture

When .NET or you need to know the current culture and localization information to format data based on the users’ location, that is all held in the CultureInfo type. To make retrieving this information you can use App.CurrentCulture() or App.CurrentUICulture(). Below is an example of just some of the information for CurrentCulture.

DOTNETTIPS-NUGET-CULTUREINFO

Once when working on a project, one of the requirements was that the user could on-the-fly change the culture that the current thread is running under. If you need to change the culture, you can do it using the methods below.

App.ChangeCulture("aa");
App.ChangeUICulture("af");

Using Common Control Characters

When creating or checking stings, there are a lot of common control characters that we use. To make using them easier, I created a static class called ControlChars. Here are its current values.

At = '@'
Back = '\b'
Backslash = '\\'
Colon = ':'
Comma = ','
Cr = '\r'
CR = '\r'
CRLF = "\r\n"
Dot = '.'
DoubleQuote = "''"
EndAngleBracket = '>'
EndComment = ')'
EndSquareBracket = ']'
FormFeed = '\f'
ForwardSlash = '/'
LF = '\n'
NewLine = "\r\n"
NullChar = '\0'
Quote = '\"'
SingleQuote = '\''
Space = ' '
StartAngleBracket = '<'
StartComment = '('
StartSquareBracket = '['
Tab = '\t'
Underscore = '_'
VerticalTab = '\v'

Since all these values is a constant, it could improve performance.

Temporary File Manager

Many apps, client and server, need to create temporary files to process data but far too many apps, even Visual Studio, do not clean up all the files they generated. So, to make creating these files easy and maintain those files, I created the TempFileManager type in the dotNetTips.Utility.Core.Windows NuGet package! I created this class a long time ago for a project written in the .NET Framework (Clr) and now I have moved it to .NET Core and made some enhancements. Below are examples of how to use it.

Creating a Temporary File

Creating a single temporary file is easy. Below is an example:

using (var tfm = new TempFileManager())
{
    var cachefile = tfm.CreateFile();

    //Process file code
}

TempFileManager implements IDisposable to ensure the files are deleted when not in use anymore. So, make sure to always use the using statement.

Creating Multiple Temporary Files

Creating multiple files at the same time is easy too.

using (var tfm = new TempFileManager())
{
    var result = tfm.CreateFiles(10);

    foreach (var file in result)
    {
        // Process file
    }

 }

All the temporary files are creating in the C:\Users\<current user>\AppData\Local\Temp folder as shown below.

DOTNETTIPS-NUGET-TEMPFILEMANAGER-FILELIST

Other Useful Methods

Here are the other methods in the class.

  • DeleteAllFiles(): Deletes the files being tracked and their names are removed from the list.
  • DeleteFile(): Deletes a single file and removes it from the list.
  • FilesList(): Returns a list of all the files being tracked.

If you find TempFileManager useful, please let me know if there is anything, I can add to make it more useful to you.

Summary

There are other minor changes to this release too including more unit tests and more benchmarking tests. I hope you will check out these methods or any of the others in the assemblies. If you have any comments or suggestions, please comment below. I’m always looking for new things for these open-source projects!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.