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.
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 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 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 Core3.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.
Here is an example of the results from my unit tests.
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.
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();
-
-
- }
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)
- {
-
- }
- }
All the temporary files are creating in the C:\Users\<current user>\AppData\Local\Temp folder as shown below.
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!