Jon Hermiz Blog

The guide to programming and analyzing SQL, .NET, and SAP

Running a .net application on a server.

The question comes up all the time across hundreds of .net forums.  Here it goes:

"I just created a vb.net application that works perfectly fine on my local machine, however I need to run this one application on a server so other users can use it.  When I try to run it on the server I get a TON of errors."

The error generally looks like this (warning: It's pretty long and ugly):

So the question is why does this happen now in .net, how can I get around it, and how do I stop it from happening in the future.  Before I get right down to the answers I would like to explain this (so you fully understand why this happens).

VB6 Gone Are The Days

Gone are the days where you could write a VB6 application, compile it, throw it on a UNC shared path and apply some security rights to your end users.  That was too simple...but in reality it was a pretty poor method of doing things.  You would have to constantly be modifying the rights on network folders, your admins hated you with a passion.

CLR and CAS

With the .net framework programs that run on the CLR use CAS (code access security).  What this means is you no longer assign rights to users / groups on a network.  Instead you assign trust to actual code that the programmer has developed.  Basically your applications assembly file is compared with the security policy of the machine.  When you run your application on your local machine and it works just brilliantly fine it's due to the fact that you are running your code in the MyComputer zone.  By default the MyComputer zone has FullTrust (unrestricted permissions) to do virtually anything.  This is why the application works on your local pc just fine...now why is it not working on the server.

It Just Wont Work On That Server

Your application bails on the server because the server is more restrictive given its zone is the LocalIntranet zone which does not have full trust to run an executable by just anyone from any machine.  In addition, it is a lot more secure (and that's the whole idea behind microsoft security from now on, make it more secure).  It also makes a lot more sense since now not anyone can just throw executables in a server shared and run them.

Lets Discuss a Complete Example

Pictures are worth 1000s of words..ya...so it's best to stop yapping and to start showing.  Let's go through a full blown example of an application that works fine on my local pc and bails on the server.  First and foremost it's worthwhile to note that on most occassions applications bail on things that access other network structures, SQL data retrieval (working with the database), etc.  The reason why I have placed a bold item on the second item is because that is what we will work on as well as in most cases this is what most people run into problems tapping into a database.

So first and foremost the application.  We are going to write a useless application that simply pulls EmployeeID numbers from the Northwind database (The sample database given to us by MS on SQL Server).  The application has no use nor will we be writing pure beautiful code that takes advantage of stored procedures, triggers, yada yada yada.  The point of this post is not how to write clean code that taps into a database, it is simply to demonstrate how to avoid the security policy error in .net.

So lets start by creating a VB winform application.

I'm using VS 2005 so you may have to work around if you are using 2003..the code and the methodology is the same in both.

Click file->project

Select Visual Basic and highlight Windows

Select Windows Application

For the name you can call it AvoidSecurityException and store it anywhere (I usually use C:\Temp for temporary projects, and you can call it whatever you want.

Now we are going to work on our project.  Drag and drop a Button onto your form, it doesnt matter where.

Double Click the button so that it takes you to the code behind page.  Since we will be dealing with databases you need to import the System.Data.SQLClient namespace.  So above the public class Form1 add the text Imports System.Data.SQLClient.

Now we have the SQLClient namespace we can start writing our code in the Button1_Click event. 

We are pretty much done, told you it was a worthless application, just to show you what happens when placing this app on a server as opposed to your local machine.  Now go ahead and build your application:

From the menu at the top select Build->Build AvoidSecurityException (the name might be different here).

Once you build this application you can run it on your local machine.  Either run it within Visual Studio, or double click the executable found in your projects bin/debug directory.  You will notice a simple loop that message boxes the employee id numbers, hopefully there isn't alot, if there is you will need to end the program (ctrl alt delete).

Great your program works, now you need to deploy it to a server so that all your other users on your network can use this program.  So you copy and paste your .exe file (the one that was in your bin/debug directory) to a network server share folder \\servername\folder.  Now you double click the exe from that shared network folder and you get that same message about an unhandled exception all the way down to System.Data.SqlClient.SqlClientPermission.

How To Avoid This

There's a couple of ways to avoid this.  You can do it the right way which takes a bit longer and seems to be a bit more complex, or you can do it the other way which is much quicker but is poor practice and a security vulnerability.

The 2 ways are:

  • Create a strong name key and use it in your applications AssemblyInfo.vb file
  • Modify the security policy to fully trust the LocalIntranet zone

The 2nd method (bad way of doing things)

(From the .net security blog: http://blogs.msdn.com/shawnfa/default.aspx)

The easiest way to modify your security policy is by using the Microsoft .NET Framework Configuration utility from the control panel.  You can also run this tool from the command line by running mscorcfg.msc.

  1. Expand the Runtime Security Policy folder
  2. Expand the Machine policy level
  3. Expand the Code Groups folder

To modify the polcy to trust a specific strong name:

  1. Right click on All_Code, and select New
  2. Create a new code group for your strong name, and hit next
  3. Select a strong name membership condition from the drop down box
  4. Hit the import button, and select your assembly.  The configuration tool will import your public key.  If you want to trust everything you sign with this key, leave the name and version boxes unchecked
  5. Select the FullTrust permission set

To modify the policy to allow full trust for all Intranet assemblies:

  1. Expand the All_Code code group
  2. Right click the LocalIntranet_Zone code group, and select properties
  3. Switch to the Permission Set tab, and select FullTrust

Reference: .net security blog

The Right Way of doing it

The correct and more preferred method is to create a strong name using the sn.exe tool and using that key in your application's AssemblyInfo file to get around these horrendous errors.  So point to your visual studio 2005 program group from the start menu.  Select Visual Studio Tools then select Visual Studio Command Line

The command line will open.  Type in:

sn -k mykey.snk

You can change mykey to any value you want such as myappskey.snk the main thing you want to make sure is you run it with the -k option.

sn -k myappskey.snk

In my apps example I will stick with mykey.snk.  Result should look much like this

Notice how the key has generated and written as mykey.snk within the active directory.  Simply take and move this key to where you would like to store it.  Make sure you place it somewhere visible to the application, in addition do not store it in a local protected folder while the application is sitting on some shared server.  It needs to be able to see it (does not mean it has to physically see it within the same directory, just means it should be able to call it or have visibility to it).  Let us say you stored the key on some shared network drive.  Fine and dandy, now we need to modify our applications AssemblyInfo file to accept this key.

So go back to your project and look in the Solution Explorer for the AssemblyInfo.vb file.  If you do not see it click the "Show All Files" icon (second small icon on the solution explorer).  Then drill down into "My Project" and you will see it:

Double click this file, and you will be presented with something like so:

You will need to add the AssemblyKeyFile attribute to this so that your assembly is aware of your key.  So you can add it anywhere in this file.  I have added it under the AssemblyTrademark:

Notice it as:

<Assembly: AssemblyKeyFile("\\networkserver\sharedfolder\mykey.snk")>

You will need to modify the path to point to where you have stored your .snk file.  Now rebuild your project.

Copy over your newly generated exe file to the shared network path so that all the other users can now run your application.  Run your application from that shared folder on that server and Voila you no longer get the security exception error.  The application message boxes the records from the database.

If You Still Get The Error

Strange, you shouldn't.  But if you did make sure your key (.snk) file is visible on some shared network folder.  Make sure your AssemblyInfo.vb file has an AssemblyVersion attribute (the line right before the last line in the image posted of the AssemblyInfo file).  Make certain you got the latest .exe compiled and that you've copied that file over to the server.

Finally last thing you can do is to select Build->Publish Project from VS 2005 and tell it to publish the .exe file to a shared (UNC) server.  Go through the wizard and get it to copy it automatically.  Sometimes you will need to install the latest .net framework on the server that hosts the exe file.

Have fun!

References:

http://blogs.msdn.com/shawnfa/default.aspx

Legacy Comments


Suresh Bansal
2007-09-04
re: Running a .net application on a server.

EXPLAINATION IS EXCELLENT AND ACCEPT MY COMPLIMENTS

Kindly explain as to how to install this sn utility from visual studio 2005 professional eddition DVD as explained by you in
sn -k mykey.snk as that did not work with us as comm

Suresh Bansal

Eralp
2007-09-15
re: Running a .net application on a server.
Thanks for explanation.

I resolved my problem via clickonce. I recommend it.( my problem is on iexplore. I just wanted to execute a console application for a VSTO Word project ( registering assembly for new taskpane and database connection ))

Eralp
Mobile Devices MVP

Hax Or
2007-09-20
re: Running a .net application on a server.
These instructions give the application a Strong Name, but it won't help execute applications on a shared network drive.

You must register the app with the GAC -or- run CASPOL to allow it.

Unless it's a 'Microsoft Strong Name' a 'Strong Name' by itself does not do anything.



Hax Or
2007-09-21
re: Running a .net application on a server.
ClickOnce will set the Policy for you for the executable you are installing, that is correct.

I prefer to use CASPOL and write my own installation programs.

Hax Or
2007-09-21
Confirmed
This was confirmed. Strong Name Key alone does not fix the issue.

"In the .NET 2.0 configuration MMC snapin, make an entry in the "Internet"
zone allowing FullTrust to assemblies exposing your strongname key. A button
is present to browse to the assembly in question."

The solution below is a command-line solution that can be incorporated in a custom 'Install' program:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\caspol.exe -m -q -ag 1 -url "file:////\\server\folder1\TEST\*" FullTrust -exclusive on

Now your strong name app will run in \\server\folder1\TEST\. This is a per machine fix that would have to be applied across all clients using the network share.




Jon
2007-09-21
re: Running a .net application on a server.
To fix the per machine issue you can run this in say ScriptLogic or any script that runs in part of a network environment. As soon as each user logs into their machine it will be registered.

Hax Or
2007-09-24
re: Running a .net application on a server.
The script should be only run once, not everytime you login.

If it runs everytime you login you will get an error message on the 2nd, 3rd, 4th logins...

Jon
2007-09-24
re: Running a .net application on a server.
Thats pretty obvious since it is a SCRIPT...
These are very fine details that should be assumed, I cannot step everyone through all of these steps, this would be a story.

Hax Or
2007-10-18
re: Running a .net application on a server.
Just clarifying in case someone thinks to put it in the Network Login Script.

Only needs to be run once, so the network admin can do this when the workstation is configured after imaging.

Great work Jon! Thank you.



Gary
2007-12-19
re: This will work, Guaranteed .
The following will work, guaranteed!

Use VB6

Click File

Select Build <your_app.exe>

Copy/move app to whatever UNC you want and run it without problems from there.

< I assume you are all sensing my sarcasm here. Yes security concerns aside, sometimes in the environment, all you need is a small app, such as a simple db front-end that will only be used by a select OU. All the advice above is brilliant, but what a hassle. >

Jon
2007-12-19
re: Running a .net application on a server.
Gary, I am not disagreeing with you but in many cases sometimes you need to use .net depending on the client and functionality. VB6 was easy and nice but it was very limited compared to what you can do with .net.


Andras Eliassen
2008-01-16
re: Running a .net application on a server.
I am sometimes tempted to use vb6, because it's simple to develop and share. However if you run a vb6 application that references dlls that are not installed on your local machine, it will not run. That anoying vbrun dll - That is an advantage with the .net applications that everything is in .net fx. And the users are very likely to have that already.

If your gui can run on .net fx alone, and it references a Business Logic Layer on another machine, then you don't have that worry about installing so much on the client machine... The GUI will run on your client, and reference the server where all the business logic (and maybe data logic) and therein additional reference are located.

So that is simpler about sharing an application that is written in vb.net instead of vb6 :)
But as you said, you are being sarcastic, and you have a good point. In general it takes a lot of time to deploy an application to users with .net (unless you are using ClickOnce publishing).

rnisupport
2008-04-22
re: Running a .net application on a server.
I have tried all of the above and it still won't work for me! if anyone is still paying attention to this subject I would like to elaborate on my situation!...
thanx

ingeb
2010-08-27
re: Running a .net application on a server.
Great explanation, Thanks.

columbia jackets
2010-10-21
re: Running a .net application on a server.
By default the MyComputer zone has FullTrust (unrestricted permissions) to do virtually anything. This is why the application works on your local pc just fine...now why is it not working on the server.


snow boots for women | columbia sportswear outlet | cheap mac makeup | the north face jackets

womens snow boots | columbia sportswear | cheap makeup | cheap north face jackets

sindhu
2011-01-22
re: Running a .net application on a server.
ssdsds

Bryan Duchesne
2011-02-14
re: Running a .net application on a server.
Can I place the .snk file in the same folder as the assemblyinfo.vb file? Alternately, when I create my InstallShield installation package, can I include the .snk in the same folder as the executable? i.e.. Program Files\myProductname

in either of the two cases, I should not have to put a file path on the .snk file definition

e.g. <Assembly: AssemblyKeyFile("mykey.snk")>


anamika saxena
2011-04-05
re: Running a .net application on a server.
hello...m new to vb 2008 expree edition...i have an application in vb 2008 express edition and it works fine in my computer.i have added COM component Microsoft Chart control in my project....I have made an .exe file for it so that it can run on another machines having dot net framework.however whenever i run this file in another computer it gives "windowsapplication1 has stopped working"....please tell me a way to run it ...i shall be highly obliged...i m in urgent need of it....

rajalakshmishanmugavel
2012-10-18
re: Running a .net application on a server.
How to run a .net program