(Print this page)

Running assemblies from a shared folder
Published date: Thursday, April 1, 2004
On: Moer and Éric Moreau's web site

After reading Rex Willis article called « Create a Stub Program for .Net » (UTMag, August 2003), I have decided to create my own application updater inspired from this article, and other I have read elsewhere and mainly from a similar application I built myself long time ago in VB6.

My own case study

The idea is quite simple: create an application that will keep in synch a shared folder of the network to a local folder. After a couple of hours of work, I had my application ready to run. I was testing my solution locally using some folders on PC. A couple of days later, when I installed it on the client server and create a shortcut a workstation, I had big (bad) surprise! A Security Exception hit me right in the face while the client was in my back. Poor me! If you don’t want to face this situation yourself, read on!

Figure 1: The "Dummy application"

To be able to thoroughly test the concept here, you will need 2 computers. These 2 PCs have to be configured to see each other (so be sure you can browse your second computer using Windows Explorer).

This article will give you some ways of being able to run your applications from a shared folder without looking an amateur.

Creating a test application

We first need to create a test application. Nothing fancy. Just something that will let us experiment the security issues.

So I have built a simple “dummy” application (see figure 1) with a label and 2 buttons. Each buttons simply displays a message box showing again, dummy answers! Here is the code:

Private Sub btnNo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles btnNo.Click
    MessageBox.Show("So here is your first one!", _
                    "UTMag demo", _
                    MessageBoxButtons.OK, _
                    MessageBoxIcon.Exclamation)
End Sub

Private Sub btnYes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles btnYes.Click
    MessageBox.Show("So here is another one!", _
                    "UTMag demo", _
                    MessageBoxButtons.OK, _
                    MessageBoxIcon.Exclamation)
End Sub
Now build your solution and copy it to a folder on you network somewhere and try to run it. It is working! A wait a minute! Why are we loosing our time (me writing and you reading) if it is working! I swear we are not loosing our precious time. The reason this application is working is simply that it is so simple that no external resources are used.

The first crash

Now, what we really want is to have this application getting the security exception and fix it. To be sure that we will be using external resources, we will make this application copy a file from the file server to a local folder (after all, that’s what I wanted to do!).

So, add another button to your form and copy this code:

Private Sub btnCrash_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles btnCrash.Click
    File.Copy(Application.StartupPath & "\test.txt", "c:\temp\test.txt", True)
    MessageBox.Show("File has been copied successfully", "File copy", _
                    MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Now rebuild your solution and recopy it to your file server. Be sure to create a file called test.txt that will reside in the same folder as your assembly on your file server (or else you will get a System.IO.FileNotFoundException exception (which is way easier to fix). Now run your application and click your new button. If you never played with the .Net security settings on your PC, you should see the exception shown in figure 2.

Figure 2: The Security exception

Enabling execution – First method

The first way of fixing this error is to trust ALL .Net assemblies executed from the local intranet. This may not be a good idea since all .Net assemblies will be trusted. In some companies it may be the way to go if you have many assemblies that you run directly from the file server.

To enable it, you need to run a wizard. This wizard is called “Microsoft .Net Framework 1.1 Wizards”. You can find it if you open the “Administrative tools” (often found into the Control Panel). Once you launched, you will see a small applet appear (see figure 3).

Figure 3: The .Net Wizards applet

As I have said, this first way will enable all .Net assemblies from the local intranet to be trusted. Double-click the “Adjust .Net Security” icon to start the “Security Adjustment Wizard”. The first step asks you if you the changes to affect the current user only or all users of this computer. Select anyone you want and click the Next button. The second step allows you to set the security level for each zone. Since our application is located on a file server of the LAN, you need to select the “Local Intranet” zone. On the slider below it, you need to set the trust to Full (see figure 4).

Figure 4: Security Adjustment Wizard

Now click the Next button. From the “Completing the Wizard” step, be sure that the security level for the local intranet zone is set to “Full Trust” and click the Finish button. If you followed the step correctly, your file should now be copied.

Again, from now on, every .Net assemblies will be able to run from the local intranet, even those that could be harmful for you computer. To reset the security back where it was (Medium Trust), use the “Default level” button in the wizard (see figure 4). If you continue to read and test the content of this article, you need to reset the security now.

Enabling execution – Second method

Instead of trusting the complete local intranet, you may want to trust a single assembly. So run the “Microsoft .Net Framework 1.1 Wizards” again. This time select the second icon, the one called “Trust an assembly” (see figure 3). Again, you are asked if the changes should affect the current user or all users of this computer. Select which ever button you want and click the Next button. The next step asks you to select the path or URL of the assembly you want to trust. The easiest is to browse to it. Once you entered it, click the Next button. The following step is title “Choose the Minimum Level of Trust for the Assembly”. Set it to “Full Trust” and click the Next button. From the “Completing the Wizard” step, be sure that the minimum level of trust is set to “Full Trust” and click the Finish button.

Try to run your application. It should be running without problem. This method has however a serious limitation. Rebuild your solution (you don’t even need to change anything). Recopy it to your file server. If you re-run it you will get the same error you had at the beginning. Why? Because the assembly had changed, it is not the same assembly anymore. It is very pleasant to re-trust your assemblies every time you rebuild them!

Solving the limitation of the second method

The second method is more secure then the first method because only one assembly is trusted instead of the complete local intranet but the rebuild error limitation is very frustrating.

There is however a very simple workaround to this. You can strong name your code. I will tell you only what’s really required about strong naming an assembly here.

First, you need to create you key pair (unless you already have one). To generate a new key pair, you use the strong name tool (sn.exe) provided with your Visual Studio .Net installation. For example, if you want to create a new random key pair, you can use this command line from the “Visual Studio .Net 2003 Command Prompt”:

Sn –k utmagdemo.snk

You can now copy your .snk file to your project folder.

The second thing you need to do is to specify your key file to your assembly. You do it by adding this line to the AssemblyInfo.vb of your project:

<Assembly: AssemblyKeyFileAttribute("utmagdemo.snk")>

The last step is simply to build it as usual. Now copy the new assembly to your file server. Try to run it. Since this assembly is new, you should get the exception. You need to, once again, use the wizard to trust the assembly but this time, unless you changed the strong naming of the application, you won’t have to reuse the wizard to trust the assembly if you build a new version.

Conclusion

I am not a big fan of running applications from a file server but some applications, like an application updater, is easier to run from a remote location.

Running application located on a file server is possible if you dare to trust it.

I hope you appreciated the topic and see you next month.


(Print this page)