Wednesday, February 07, 2007

Running .NET Apps from Network Shares

One of my current projects requires that my application run from a network share. Not thinking that this would be a problem, I wrote my application and went to deploy it and amazingly, it didn't run. It threw a security error. After some digging I found out that .NET apps don't run with full trust when running from network shares (thankfully, big security problem if they did). They actually don't run with enough trust to even load the main form.

I found a thread that mentioned the solution: http://www.vbdotnetforums.com/showthread.php?t=1224 . Basically you just need to setup the security.config for the machine to grant full trust to your application. You can do it by hand or you can use the CASPOL utility that comes with .NET framework.

Config Files and Assemblies in the GAC

Be sure to read the update at the bottom of the post.

The 2.0 version of the .NET has improved the application configuration functionality a lot. Read/Write capability being one of the nicest new features. Combined with Visual Studio 2005’s
new settings dialog, using the app.config has gotten a lot easier.

One of the main rules when using the app.config, is that the app.config file has to be in the same folder as its owning dll or exe. Which usually isn’t a problem unless your dll is sitting in the GAC. If you’ve had any experience with the GAC, you know that you can’t just add files to it. It only really accepts .NET dlls.



My current project requires a business layer that will be used by multiple applications, which is a great use of the GAC. There are some settings that will be needed by this business layer. So the question is: How do I get the app.config settings to work with a dll that is stored in the GAC?
It took some figuring out but I found a way. It's not the cleanest way but it works.

Here how:

  1. Copy your dll to the GAC (however you normally do it)

  2. Open command prompt (Start -> Run -> cmd)

  3. Change the path to Windows Root Folder\Assembly

  4. Depending on what you have installed Change the path to:

    • .NET 1.0 or .NET 1.1: cd GAC
    • .NET 2.0: cd GAC_MSIL

  5. If you dir, you will see a list of all the assemblies installed into the GAC. Cd into your assembly's folder
  6. If you dir again, you will see one folder with your assembly's version and public key token. Cd into this folder
  7. If you dir again, you will be glad to see your assembly.
  8. Copy your config file to this folder via the command prompt
  9. Your application should now be able to locate and use any configuration that you have added to that file.
UPDATED: Turns out that I'm only partially correct with the above post. You can put files into the GAC folders using the above steps. However, you cannot use the built in app.config settings functionality. For some reason it won't read in the file. I've since replaced the app.config settings with a custom class that has all the values that I want to use as settings and then serialize/deserialize the object to the same directory as the owning application or dll.


UPDATED 2: Thanks to commenters on further research, the above option of serialization is not required. All you need to do is setup your settings for the built in app.config funcationality and then use the OpenMappedExecConfiguration method. Example:


   Private Shared Function GetConfigurationSection() As Configuration.ClientSettingsSection 
Dim codebase As String = System.Reflection.Assembly.GetExecutingAssembly().CodeBase
Dim fileMap As New Configuration.ExeConfigurationFileMap()
Dim p As New Uri(codebase)
Dim localPath As String = p.LocalPath
Dim executingFilename As String = System.IO.Path.GetFileNameWithoutExtension(localPath)

Dim sectionGroupName As String = "applicationSettings"
Dim sectionName As String = String.Format("{0}.My.MySettings", executingFilename)

Dim configName As String = String.Format("{0}.config", localPath)

fileMap.ExeConfigFilename = configName
Dim config As Configuration.Configuration = _
Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, Configuration.ConfigurationUserLevel.None) 'System.AppDomain.CurrentDomain.)

If config IsNot Nothing Then
Dim group As Configuration.ConfigurationSectionGroup = config.GetSectionGroup(sectionGroupName)

If group IsNot Nothing Then

Return DirectCast(group.Sections(sectionName), Configuration.ClientSettingsSection)
End If
End If
Return Nothing
End Function




Sunday, February 04, 2007

Another handy link

CellSwapper is a cool service that helps you find someone to take over you cell phone account by transferring your account to someone else.

http://feeds.feedburner.com/~r/Techcrunch/~3/73811460/

VMware Converter

Found this news item the other day. This can change a lot how we do things.

http://news.com.com/2110-1010_3-6154353.html?part=rss&tag=2547-1_3-0-5&subj=news