Unblock files received from email or the internet in C#

C# IT Development

I do a lot of technical editing. When a project editor sends me files, Windows marks them as from an “untrusted” source. Then when I try to open the files in Word, it warns me and asks if I want to open the file anyway.

This is kind of like taking candy from people. In general you shouldn’t take candy from stranger or trust files that you receive in emails. In this case, however, I know that the files are safe, so it’s just annoying.

If you right-click one of these files in File Explorer and select Properties, you’ll see something like the following picture.

You can see the warning at the bottom. You can unblock files one at a time by checking the Unblock box and clicking Apply. Unfortunately if you select multiple files, the Properties dialog does not give the warning or display the checkbox.

Again, all of this makes sense so I’m not complaining. These are sensible safety precautions for most people. I just have an unusual situation that makes this unnecessary.

This example lets you unblock files quickly and easily. Do not use this method unless you understand it and you know that the files are safe!

The following section explains how the program lets you select and unblock files. The sections after that fill in a few details including how the listbox displays file names and how the CheckAll extension method lets you check all of the items in a checked listbox.

Unblocking Files

When you select the File menu’s Open command, the program executes the following code.

// Let the user select some files.
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (ofdFiles.ShowDialog() == DialogResult.OK)
{
// Add the selected files to the lists.
clbFiles.Items.Clear();
foreach (string filename in ofdFiles.FileNames)
{
FileNameInfo name_info = new FileNameInfo(filename);
int index = clbFiles.Items.Add(name_info);
}

// Check all of the files.
clbFiles.CheckAll();
}
}

This code displays a file selection dialog that you can use to select one or more files. If you select files and click OK, the code loops through the selected files, uses each to create a new FileNameInfo object (described shortly), and adds them to the clbFiles checked listbox control. It finishes by calling the CheckAll extension method (also described shortly).

When you click the Unblock button, the following code executes.

// Unblock the files.
private void btnUnblock_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;

int num_unblocked = 0;
foreach (FileNameInfo name_info in clbFiles.CheckedItems)
{
string filename = name_info.FullName;
if (UnblockFile(filename)) num_unblocked++;
}

// Uncheck all of the files.
clbFiles.UncheckAll();
Cursor = Cursors.Default;

MessageBox.Show(string.Format(“Unblocked {0} files.”, num_unblocked));
}

This code loops through the checked items in the listbox. Note that the items in the listbox are FileNameInfo objects, so that’s the kind of object that the code uses to loop through the CheckedItems collection. For each checked item, the code gets the file name and calls the UnblockFile method described next.

The following code shows the UnblockFile method.

// Unblock the file and return true if successful.
// This method seems to return false if there is
// a problem rather than throwing an exception.
public bool UnblockFile(string fileName)
{
return DeleteFile(fileName + “:Zone.Identifier”);
}

This method simply calls the DeleteFile method defiend in the kernel32 library, passing it the name of the file with “:Zone.Identifier” appended. This removes the zone identifier that marks the file as blocked.

To use DeleteFile, the program must know where to find it. The following code fragment tells the program where to look.

using System.Runtime.InteropServices;

public partial class Form1 : Form
{
[DllImport(“kernel32”, CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteFile(string name);

}

The code imports System.Runtime.InteropServices so it can later use the DllImport and MarshalAs attributes. Inside the Form1 class, it uses those attributes to indivcate where to find DeleteFile.

It’s that simple! Now you can select and unblock files en masse.

The following sections described two other useful features demonstared by this program.

Displaying File Names

The CheckedListBox control (as well as the ListBox and ComboBox controls) display lists of objects. To degtermine what to display, the control uses the objects’ ToString methods. This example uses the following FileNameInfo class to represents files within the list.

internal class FileNameInfo
{
internal string Name;
internal string FullName;

internal FileNameInfo(string full_name)
{
FileInfo file_into = new FileInfo(full_name);
Name = file_into.Name;
FullName = full_name;
}

public override string ToString()
{
return Name;
}
}

This class simply stored a file’s short and full names. It has an initializing constructor that makes it easy to set those values.

It also overrides the class’s ToSrtring method so it displays the file’s short name. The listbox uses that method, so it displays the file’s short name.

If you look at the earlier code that executes when you click Unblock, you’ll see that it uses the FileNameInfo object’s FullName values to get the files’ full names.

This is a very useful technique for storing data in listbox items. Create a class that holds the data. Then override the class’s ToString method to give the listbox something to display.

Checking and Unchecking Items

For some reason, the CheckedListBox control does not have methods to check or uncheck all items. That seems like an obvious oversight, but it’s easy to fix by simply creating a extension methods.

Recall that extension methods must be static methods defined inside a static class. The following code shows this example’s extension methods.

public static class Extensions
{
private static void CheckUncheckAll(
this CheckedListBox clb, bool is_checked)
{
for (int i = 0; i < clb.Items.Count; i++)
{
clb.SetItemChecked(i, is_checked);
}
}

public static void CheckAll(this CheckedListBox clb)
{
clb.CheckUncheckAll(true);
}

public static void UncheckAll(this CheckedListBox clb)
{
clb.CheckUncheckAll(false);
}
}

The class defines a CheckUncheckAll method that sets all of the control’s items to either checked or unchecked. This method is an extension method because it is static and its parameter list begins with the this keyword to identify the object that it extends. Notice, however, that the method is private, so it is only accessible inside this class. This method ismply loops through the list’s items and calls the control’s SetItemChecked method to check or uncheck each item.

The CheckAll extension method is public. It calls the CheckUncheckAll method passing it the value true to check all of the control’s items.

Similarly the public UncheckAll extension method uses the CheckUncheckAll method to uncheck all of the items.

You cna use similar techniques to perform other operations on listboxes. For example you could write extension methods to select or deselect all items.

Summary

This example lets you quickly unblock files en masse. The key is the DeleteFile method, but you may also find the technique for storing data in listbox items useful, as well as the CheckAll and UncheckAll extension methods.

     

The post Unblock files received from email or the internet in C# appeared first on C# Helper.