Home > Articles > Programming > Windows Programming

  • Print
  • + Share This
Like this article? We recommend

Like this article? We recommend

Repairing the Errors

Let's look at a few of the issues that FxCop found. The sample application uses frmMain for the name of the form. FxCop marked this usage as an error because standard convention is to use Pascal case for class names. In addition, frm isn't a word, so FxCop suggests correcting the spelling of the word. Simply changing the name of the class to FormMain (initial capital letter and recognizable name) clears up this problem. More importantly, this change makes the class name easier to read and understand. However, the code executes much as it did before—nothing has really changed.

The next error concerns Common Language Specification (CLS) compliance. The application doesn't indicate whether it's compliant with CLS. A CLS-compliant application only uses features that are available as part of CLS. For example, if your C# application uses a UInt32 variable, it's not CLS compliant because the UInt32 type is a language-specific feature. The purpose in marking an application as CLS compliant is to indicate that it can run in any environment that completely emulates CLS. Using a UInt32 datatype would mean that you could run the application only on a Windows system that allows access to unsigned integers. Here's how you would indicate that an entire assembly is CLS compliant:

// Define the assembly as CLS compliant.
[assembly:CLSCompliant(true)]
namespace SimpleApp
{
  ... Other Code ...
}

You can mark sections of an application as noncompliant using the same attribute. For example, if the whole application is CLS compliant except for one method that uses a UInt32, you could mark the method like this:

[CLSCompliant(false)]
private void btnTest_Click(object sender, System.EventArgs e)
{
  UInt32 NonCLSVariable; // UInt32 is not CLS compliant.

  // Initialize the variable.
  NonCLSVariable = 3;

  // Display a message.
  MessageBox.Show("The value is: " + NonCLSVariable.ToString());
}

Marking an assembly might not seem like a very big deal, but consider the changes that are happening with computing as a whole. The application you build today on a 32-bit machine might have to execute on a 64-bit machine tomorrow. Considering CLS issues today means you'll have less work to do to update the application tomorrow.

The next issue is the first security consideration. I don't know of any application authors who mark their assembly's security needs today—and that's a problem. FxCop marks out minimal essential security requirements. The first is to tell the Common Language Runtime (CLR) what resources your application actually needs. In this case, the application only needs to display a message, and should be marked as such. More importantly, the application should contain information about resources that it doesn't need. For example, this application doesn't need to access the hard drive, so you can deny hard drive access. Adding this information prevents a virus from gaining access to those resources even if it infiltrates the application. Here are some typical assembly-level security descriptions:

// Define the security needs for the assembly.
[assembly:EnvironmentPermissionAttribute(SecurityAction.RequestRefuse)]
[assembly:FileIOPermission(SecurityAction.RequestRefuse)]
[assembly:RegistryPermission(SecurityAction.RequestRefuse)]

These three assembly-level permissions tell CLR that it shouldn't allow the application to do anything with environmental variables, access the disk drive, or change the registry. If a virus infects this application, it won't be able to do many of the things that viruses commonly do, such as infecting disk files with virus information. The virus can't move data around, or make itself permanent, for that matter. The .NET Framework provides a wealth of permissions that you can use to control your application. Here are some of the common permissions you should consider:

  • EnvironmentPermissionAttribute

  • FileDialogPermissionAttribute

  • FileIOPermissionAttribute

  • IsolatedStoragePermissionAttribute

  • PermissionSetAttribute

  • PrincipalPermissionAttribute

  • PublisherIdentityPermissionAttribute

  • ReflectionPermissionAttribute

  • RegistryPermissionAttribute

  • SecurityPermissionAttribute

  • SiteIdentityPermissionAttribute

  • StrongNameIdentityPermissionAttribute

  • UIPermissionAttribute

  • UrlIdentityPermissionAttribute

  • ZoneIdentityPermissionAttribute

A second security error is that this assembly isn't signed. An assembly with a strong name is harder to tamper with and therefore harder to corrupt. The strong name doesn't protect the assembly from prying eyes—you need a product such as Dotfuscator to modify the code in such a way that others can't really understand what you're doing. To add a strong name to your assembly, use the SN (strong name) utility to create a key pair like this:

sn -k MyKey

It's important to protect this key because someone else could use it to modify your code.

In addition, you should sign all of your code using the same key or designate a specific key for each purpose. Once you generate a key, you add it to your code using a special attribute, like this:

[assembly: AssemblyKeyFile("MyKey")]
  • + Share This
  • 🔖 Save To Your Account