C# Snippets

Here are useful snippets of code I've picked up or developed myself while programming in the C# language.

Using a Struct "globally"
Check if Object has Method
Get Command Line Arguments
Open a File with the Default program
Using a Mutex to ensure Single App Instance
Truly random number generation


Move a form that doesn't have a titlebar:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MoveFormWithoutTitlebar {
    public partial class Form1 : Form {

        
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;
        
        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd,
                         int Msg, int wParam, int lParam);

        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();
        

        public Form1() {
            InitializeComponent();
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }
    }
}


Computer hashes of strings:


    //requires using System.Security.Cryptography;

    static string GetSHA1 (string ipString) {
        SHA1 sha1 = new SHA1CryptoServiceProvider ();
        byte[] ipBytes = Encoding.Default.GetBytes (ipString.ToCharArray ());
        byte[] opBytes = sha1.ComputeHash (ipBytes);
 
        StringBuilder stringBuilder = new StringBuilder (40);
        for (int i = 0; i < opBytes.Length; i++) {
            stringBuilder.Append (opBytes[i].ToString ("x2"));
        }
 
        return stringBuilder.ToString ();
    }
 
    static string GetMD5 (string ipString) {
        MD5 md5 = new MD5CryptoServiceProvider ();
        byte[] ipBytes = Encoding.Default.GetBytes (ipString.ToCharArray ());
        byte[] opBytes = md5.ComputeHash (ipBytes);
 
        StringBuilder stringBuilder = new StringBuilder (40);
        for (int i = 0; i < opBytes.Length; i++) {
            stringBuilder.Append (opBytes[i].ToString ("x2"));
        }
 
        return stringBuilder.ToString ();
    }
}


Handle the X in Form's Control Box

This example detects whether or not Application.Exit() was invoked. If not, it balks:

private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            if (e.CloseReason == CloseReason.ApplicationExitCall) {
                savePreferences();
            }
            else {
                if (e.CloseReason == CloseReason.UserClosing) {
                    MessageBox.Show("Please only use the File->Exit menu or the Escape key to exit application",
                        "Please don't user the Close button");
                    e.Cancel = true;
                }
            }            
        }


Extract an executable's icon:

The ExtractAssociatedIcon static method on the Icon class (in System.Drawing) extracts the associated icon from any file. By supplying the Application.ExecutablePath (in System.Windows.Forms), you extract the application's own icon.

    form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath );

Resolve Shortcut link (*.lnk) into the full path of target file

Add a reference to Microsoft Shell Controls and Automation to your project. Then add the method shown below:

public string GetShortcutTargetFile(string shortcutFilename) {
    string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
    string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);

    Shell32.Shell shell = new Shell32.ShellClass();
    Shell32.Folder folder = shell.NameSpace(pathOnly);
    Shell32.FolderItem folderItem = folder.ParseName(filenameOnly);
    if (folderItem != null) {
        Shell32.ShellLinkObject link =
        (Shell32.ShellLinkObject)folderItem.GetLink;
        return link.Path;
    }
    return ""; // not found
}

Use File Menu to Open a Text File

A frequent task in programming is to open a text file and either read its contents into a string or a textbox. Here, I'll show you methods you can use to accomplish this using a File->Open menu item. To begin with, start a new Windows Forms Project in Visual Studio. Drag and drop a menuStrip control onto the form, then add a File menu and an Open submenu:

enter image description here

Double-click the Open submenu item, so that the IDE creates the following method:

enter image description here

Now let's write code to actually implement opening a text file and reading-in its contents. Enter the following code into your openToolStripMenuItem_Click() event-handler:

    string sFile = getFilenameToOpen();
    if (sFile.Length > 0) {
        sFile = OpenTextFileReturnContents(sFile);
    }

The IDE should prompt you to create method stubs for methods getFilenameToOpen() and OpenTextFileReturnContents(). I show full code for these two methods below:

    private string getFilenameToOpen() {            
        OpenFileDialog openDlg = new OpenFileDialog();
        openDlg.Filter = "Text Files (*.txt)|*.txt";
        openDlg.InitialDirectory = Path.GetDirectoryName(Application.ExecutablePath) + "\\";
        openDlg.FileName = "";
        openDlg.CheckFileExists = true;
        openDlg.CheckPathExists = true;
        if (openDlg.ShowDialog() == DialogResult.OK) {
            return openDlg.FileName;
        }
        return "";
    }

The method I've just shown you will return either a zero-length string, if an appropriate file was not selected (such as when the user cancels the file-open dialog), or else it will return a string representing the full path to a text file. Notice that I've set the .Filter property of the dialog so that only text files will be shown.

I've set the .InitialDirectory property so that the dialog always initially opens onto our application's executable directory. You can comment this line out if you don't desire this behavior. I've also set properties so that the dialog checks the validity of the path and file selected by the dialog. After all, we don't want to return a filepath string to a file that doesn't exist!

Now we have a method written for getFilenameToOpen(). Notice that in the menu's click event-handler, we use a conditional to test that the length of the string returned is greater than zero. We know that getFilenameToOpen will return a zero-length string if there's any problem selecting a valid file using the file-open dialog.

Therefore, by testing that the returned string is greater than zero in length, we assure ourselves that all is as it should be.

    private string OpenTextFileReturnContents(string sFile) {
        string txtFileContents = string.Empty;
        using (StreamReader sr = new StreamReader(sFile)) {
            txtFileContents = sr.ReadToEnd();
        }
        return txtFileContents;
    }

And that's it! We now have code to open a text file using a file-open dialog, and read its contents into a string variable! Please note that you must have a using System.IO using statement in your code, or else method OpenTextFileReturnContents() won't work and the program won't compile.

You can download a zipped template importable into Visual Studio that gives you the functionality shown in this document.

Download the OpenTextFile.zip template.

Place it in:

./Visual Studio 2010/My Exported Templates/ 

Gets all files within a given folder, or gets all files just from the root of that folder (and not from any subfolders):

//obtain the directory we're wanting to search for files...

if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
    folderToSearch = folderBrowserDialog1.SelectedPath; //make folderToSearch a form-level public variable                
}

//if we want only top-level files (those not in subfolders of folderToSearch), then...

DirectoryInfo di = new DirectoryInfo(folderToSearch);
FileInfo[] fi = di.GetFiles("*.*", SearchOption.TopDirectoryOnly);
            
//if we want to include subdirectories in our search:

DirectoryInfo di = new DirectoryInfo(folderToSearch);
FileInfo[] fi = di.GetFiles("*.*", SearchOption.AllDirectories);
            
//now the fi array instance contains full paths of all found files (let's put filenames in a listbox):

lstFiles.Items.Clear();
foreach (FileInfo filinf in fi) {
    lstFiles.Items.Add(Path.GetFileName(filinf.FullName));
}

You can click here to download a fully functional demo C# project.


Demonstrates how to securely wipe (i.e., delete) a file in C#:

        private void secureFileWipe(string origFile) {
            if (File.Exists(origFile)) {
                
                try {
                    File.SetAttributes(origFile, FileAttributes.Normal);
                    double sectors = Math.Ceiling(new FileInfo(origFile).Length / 512.0);
                    byte[] dummyBuffer = new byte[512];
                    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                    FileStream inputStream = new FileStream(origFile, FileMode.Open);
                    inputStream.Position = 0;
                    for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++) {
                        rng.GetBytes(dummyBuffer);
                        inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                    }
                    inputStream.SetLength(0);
                    inputStream.Close();
                    DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
                    File.SetCreationTime(origFile, dt);
                    File.SetLastAccessTime(origFile, dt);
                    File.SetLastWriteTime(origFile, dt);
                    File.SetCreationTimeUtc(origFile, dt);
                    File.SetLastAccessTimeUtc(origFile, dt);
                    File.SetLastWriteTimeUtc(origFile, dt);
                    File.Delete(origFile); // Finally, delete the file
                    Debug.WriteLine("Successfully securely deleted file '" + Path.GetFileName(origFile) + "'");
                }
                catch (Exception ex) {
                    Debug.WriteLine(ex.Message, "Error securely deleting file");
                }
            }
        }

Open File Dropped Onto Form

Example written 01/13/2011

The following code shows how to implement functionality in your Windows Forms application, such that you'll be able to open a file that is dragged and dropped onto your program's form. This behavior is often desirable for programs that manipulate files in some way (renamers, encrypters, etc.) It's also nice for the user to be able to have more than one way to open a file. This example implements opening via drag-dropping, and via a customary File->Open menu.

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace BryanWinForms1 {
    public partial class Form1 : Form {

        private delegate void DelegateOpenFile(String s); //define delegate type
        DelegateOpenFile _openFileDelegate; //declares a delegate instance

        public Form1() {
            InitializeComponent();
            this.AllowDrop = true; //must set this to true, for dragDrop to work
            //delegate needed so Form1_DragDrop() can asynchronously
            //invoke our program's OpenFile() method
            _openFileDelegate = new DelegateOpenFile(this.OpenFile); //instantiates delegate
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e) {
            OpenFileDialog openDlg = new OpenFileDialog();
            openDlg.Filter = "Any File (*.*)|*.*";
            openDlg.FileName = "";
            openDlg.CheckFileExists = true;
            openDlg.CheckPathExists = true;

            if (openDlg.ShowDialog() != DialogResult.OK)
                return;

            OpenFile(openDlg.FileName);
        }

        private void OpenFile(string sFile) {
            //insert appropriate file-opening code here...
            MessageBox.Show("\"" + sFile + "\" will be opened.");
        }

        private void Form1_DragEnter(object sender, DragEventArgs e) {
            //we're only interested if a FILE was dropped on the form
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;
        }

        private void Form1_DragDrop(object sender, DragEventArgs e) {
            //good idea to use try-catch block, in case something goes wrong
            try {
                Array a = (Array)e.Data.GetData(DataFormats.FileDrop);
                if (a != null) {
                    // Extract string from first array element
                    // (ignore all files except first if number of files are dropped).
                    string s = a.GetValue(0).ToString();
                    // Call OpenFile asynchronously.
                    // Explorer instance from which file is dropped is not responding
                    // the entire time that the DragDrop handler is active, so we need to return
                    // immidiately (especially if OpenFile shows MessageBox).
                    this.BeginInvoke(_openFileDelegate, new Object[] { s });
                    this.Activate();        // in the case Explorer overlaps this form
                }
            }
            catch (Exception ex) {
                Trace.WriteLine("Error in DragDrop function: " + ex.Message);
                // don't show MessageBox here - Explorer is waiting !
            }
        }
        
        //next right-brace ends Form1 class
    }
    //next right-brace ends namespace
}

Demonstrates how to implement a simple splash form that will display for a brief time before your main form.


       public Form1() {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }
        

        private void Form1_Load(object sender, EventArgs e) {
            
            Form splash = new Form();
            splash.Size = this.Size;
            splash.StartPosition = this.StartPosition; //same as Form1
            splash.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            //splash.BackgroundImage = ExcuseManager.Properties.Resources.kyr_splash;

            this.Hide();    //hide our main form...
            splash.Show();  //...and show splash screen

            System.Threading.Thread.Sleep(3000);
            splash.Dispose(); //leaving Form1 visible
         
        }
        

Open folder programmatically using Windows' Explorer:

        private void frmMain_MouseClick(object sender, MouseEventArgs e) {
            switch (e.Button) {
                case MouseButtons.Left:
                    break;
                case MouseButtons.Right:
                    string path = Path.GetDirectoryName(Application.ExecutablePath);                       
                    System.Diagnostics.Process.Start("explorer.exe", path);
                    break;
                default:
                    break;
            }

        }

Use mutex to ensure single instance

Often, we don't want more than one instance of our program running simultaneously. To ensure that only one instance is allowed to run at any given time, we can use what's known as a mutex. From the MSDN website, Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex. So, by causing our program (in the Program.cs file) to acquire a mutex, we'll prevent other instances of it being run in other threads.

We're going to modify our Program.cs file (see it near the bottom of the Solution Explorer screenshot below). We'll only add a few lines of code, but it will ensure that only one instance of our program can run at any given time.

enter image description here

using System;
using System.Windows.Forms;

namespace MyNamespace
{
    static class Program
    {
        /// 

        /// The main entry point for the application.
        /// 

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);           
            bool ok;
            System.Threading.Mutex m;
            //the string parameter in the following line could be any sufficiently lengthy (and hence, likely unique, string)
            m = new System.Threading.Mutex(true, "makeThisSomeHighlyUnlikelyStringOfConsiderableLengthAndUniqueness", out ok);
            if (!ok)
            {
                MessageBox.Show("Another instance is already running.");
                return;
            }
            Application.Run(new frmMain());
            GC.KeepAlive(m);
        }
    }
}

Without the mutex implementation shown above, our code would instead be a few lines shorter, as shown below:

using System;
using System.Windows.Forms;

namespace MyNamespace
{
    static class Program
    {
        /// 

        /// The main entry point for the application.
        /// 

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);                       
            Application.Run(new frmMain());
        }
    }
}


Example of using the BackgroundWorker component

Shows how to use the BackgroundWorker component to execute lengthy operations on a separate thread (prevents your UI from "stuttering"). The example project can be downloaded here (51.9 Kb).

enter image description here

Speaking generally, you can use a lamba expression to invoke any sort of process on its own thread, if you think it may take awhile to complete:

new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt")).Start();

In the case of a backgroundWorker, you'd normally invoke it asynchronously, thusly:

backgroundWorker1.RunWorkerAsync();

The

backgroundWorker's ProgressChanged()

event is raised on the main UI thread, so it's okay to put code in

ProgressChanged()

that updates the UI. But don't place UI-updating code in

Do_Work()

. You can give the Do_Work method the following attribute to prevent it from stopping if an exception is raised:

[System.Diagnostics.DebuggerNonUserCodeAttribute()] 

Accessing a form's textbox from within another class

Shows how we can access Form1's default TextBox (textBox1) from within another class, by passing into that other class's constructor a refence to Form1. We create public properties for the form's 'textBox1' TextBox, because the textbox is private to Form1 (see the declaration in Form1Designer.cs, which looks like this):

private System.Windows.Forms.TextBox textBox1;

By passing a reference to Form1 into the other class's constructor, and then utilizing the properties we created, we can alter Form1's textbox's .Width and .Text properties from another class.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace testApp {
    public partial class Form1 : Form {

        public Form1() {
            InitializeComponent();
        }

        public string TextValue { 
            set { textBox1.Text = value; } 
        } 
 
        public int TextWidth { 
            set { textBox1.Width = value; } 
        }

        private void button1_Click(object sender, EventArgs e) {
            OtherClass oc = new OtherClass(this);
        }
    }

    public class OtherClass{
        Form1 f2;
        public OtherClass(Form1 f) {
            f2 = f;
            f2.TextValue = "Hello World!";
            f2.TextWidth = 200;
        }

    }
}