• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1103
  • Last Modified:

non-traditional App.config needed

Hi,

I am deploying an assembly that is configured at runtime from an app.config file.

The app.config file is named after the entry point EXE like:  myexe.exe.config

I would like to do away with the current config file and either embed the config file as an embeded resource, or otherwise hide it. Does anyone know how this is done?

Thanks
0
gregasm
Asked:
gregasm
  • 11
  • 6
  • 6
  • +4
5 Solutions
 
mmarinovCommented:
Hi gregasm,

i think that is will be much easy if you use registry,  isn't it ?

B..M
0
 
gregasmAuthor Commented:
No registry.

It is configuration information that I need to read from somewhere....

looks like this:

<configuration>
      <configSections>
            <section
                  name="uipConfiguration"
                  type="Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler,  Microsoft.ApplicationBlocks.UIProcess, Version=1.0.1.0,Culture=neutral,PublicKeyToken=null" />
    </configSections>
   
    <uipConfiguration>
        <objectTypes>
                  <iViewManager
                        name="WizardViewManager"
                        type="Microsoft.ApplicationBlocks.UIProcess.WizardViewManager, Microsoft.ApplicationBlocks.UIProcess, Version=1.0.1.0,Culture=neutral,PublicKeyToken=null"
                        />
            <state ....


I'd like this to not be appname.exe.config.. but rather... embedded in the dll or exe as a embedded resource?

Even put in sql server is better than being a file outside sitting in the deployment directory
0
 
mmarinovCommented:
i'm not sure it can be done as i've searched for this too
if there is a solution it will be helpfull to me aslo

B..M
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
gregasmAuthor Commented:
Look at this link:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/uipab-ch04.asp

And in table 4.2, it says:

Attack techniques The attacker deploys malicious assemblies on the client and alters the configuration file to force UIP to load the malicious assemblies. The attacker can then take control of the workflow.  

Countermeasures Use the Configuration Management Application Block (CMAB) to increase the level of protection for the configuration file needs.

*****Specify another resource, such as the SQL Server computer, to provide the configuration information, instead of the traditional ExecutableAssemblyName.exe.config. *****


The line with the asterisks suggests that it IS possible, but afterwards, does not say how...
 
0
 
mmarinovCommented:
the CMAB is not embeded the config file, but what it is doing is to store the configuration properties not in web config but in the database, but you have to declared which will the assemblies that will catch those configuration properties

in my case use CMAB and it is working GREAT
download it and see the examples and help that is provided

B..M
0
 
gregasmAuthor Commented:
Well, I should have editied any reference to CMAB out of the previous post.  I read up on the CMAB documentation, and it is quite clear that CMAB is not necessary to store the config file and retrieve it from somewhere else, other than from within the same directory, named myexe.exe.config.

I am glad that I don't HAVE to use CMAB because that would introduce more dependencies to my project.

How can I do it without using CMAB? That is the question. Thanks,
0
 
mmarinovCommented:
i've understiid you for this - Unfortunatelly i can not help you on this :(

B..M
0
 
gregasmAuthor Commented:
Hey thanks for writing in this thread! I will definitely let you know when I find out how it is done.
0
 
LacutahCommented:
Dumb question, why not create a private class in your project full of configuration properties, and reference static constants from that class?   This way at least you'll have all config information in one place, and it'll be compiled into your application.
0
 
gregasmAuthor Commented:
The configuration file does more than store name value pairs. Please make sure you understand the question fully first.
0
 
etmendzCommented:
If you do not want your config to be in a text file, you can use a database like MS Access, SQL Server or MSDE. You actually store the entire config to a single table field which uses a data type that supports the storage and retrieval of large amounts of data (like text, ntext, memo, image, blobs, etc.). You can encrypt the config when you store to your database then decrypt it when you retrieve from your database.

Since the traditional .config file is supported by the runtime, your config in your database must be manually loaded. That brings up some extra work but consider that it also means you can create your own XML schema for the config. You can more or less base the structure on the structure of the traditional .config if you like.

Of course, you must create your own config parser/loader class. The power of having your own config schema and parser/loader is that you can deploy configurations that are consumed by .exe and/or .dll assemblies (traditional .config does not support loading from .dll). This is important in my experience when working with .Net and COM+ where you deploy only .dll files.

After you've retrieved, decrypted and loaded the config from the database to say a text/stream object, process it using your config parser/loader. If memory permits, you can achieve all of these without having to write the config to a file. Also, if memory permits, you can store/cache the entire parsed/loaded config in memory during the entire application lifetime.

Caching is an important factor when optimizing for performance and resource utilization especially when you reach that point when some configurations may be shared by the many applications running on the same machine. You can follow the caching technique in CMAB, CAB or you can create your own.

Have fun.
0
 
vascovCommented:
Have a look at this sample that may give you some hints:
http://www.theserverside.net/discussions/thread.tss?thread_id=25076

If all you want is to store your own user settings, a suggestion is to simply use a DataSet (persisted as a simple .xml file) and then just add it as a resource to your assembly, and in runtime just read it.

Something like:
config.xml
<MyConfig>
  <IAmASetting>Set me</IAmASetting>
</MyConfig>

mylib.cs:
// compile with: csc /t:library mylib.cs /res:config.xml,config.xml
using System;
using System.Data;
using System.Diagnostics;

public class SomeClass
{
      private DataSet sett = null;

      public SomeClass()
      {
            sett = new DataSet();
            sett.ReadXml( System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream( "config.xml" ) );
      }

      public string GimmeTheSetting( string Setting )
      {
            return sett.Tables[ "MyConfig" ].Rows[0][ Setting ].ToString();
      }
}

myapp.cs
// compile: csc myapp.cs /r:mylib.dll
using System;

class App
{
      public static void Main()
      {
            SomeClass slc = new SomeClass();
            Console.WriteLine( slc.GimmeTheSetting( "IAmASetting" ) );
      }
}


If you want to get fancier, than just have a class xml serializable and use the XmlSerializer to deserialize it into an object.

Note that storing the config file in the assembly is a one way travel, you can read, but you cannot edit it, you'll need to recompile. (that's actually not totally correct, but you'll want to recompile)

hth

Vasco
0
 
nauman_ahmedCommented:
Check the following tutorial where it is described how to embed .manfiest file in your .exe or DLL. The same logic you can apply for your app.config files.

http://www.codeproject.com/csharp/dotnetvisualstyles.asp

Best, Nauman.
0
 
vascovCommented:
I don't think that will work for config files.
Have you actually tried it and it worked ? (i'm not picking on you, but i would be really surprised (positively:) if it did)

I think that manifests are an XP OS feature. They have a schema of their own. Mostly, i believe it's used by the OS Loader (as it is when you want XP styles, which is effect redirects the loading of one dll to another) to do side-by-side config.

I would be interested to know if this works with your .config files.

Vasco
0
 
etmendzCommented:
Actually, the manifest is a .Net feature that allows you to describe an assembly (a .dll file) or a collection of different assemblies (many .dll filesl) into a single assembly/.dll file. This feature is similar to a feature in J2SE/J2EE where manifests describe the collection of classes that make up a .jar file or an application/component deployment.

But I also doubt that the manifest specs should work for .config.

The manifests and .config files are .Net specs driven and are, therefore, bound to the limitations of the .Net specs for these files. If you want flexibility, you'll have to build your own engine that serves your specific purpose.

While .config offers something built-in to get you started fast (.Net is still about productivity), you are NOT required to use it and you are NOT suppose to be limited by it. You can learn from it and create your own. It is good enough to have something to use when you need it fast. But that doesn't mean you are not allowed to invent on top of what you get out of the box.

Have fun.
0
 
nauman_ahmedCommented:
gregasm,

Did you try embedding the app.config file in your application and accessing it in your code? If you are using app.config just to store string values, then I will recommend you embed that in .resx file as that is the best place. Check out the following ee post for embedding and retrieveing resources:

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_21160955.html#12259330

Best, Nauman.
0
 
vascovCommented:
Hmm, actually i still believe manifests are NOT a .NET feature, but rather a feature used by .NET
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sbscs/setup/manifests.asp)
(you can still have manifests on xp+ for any app without .NET, but you cannot have manifests on w2k even WITH .NET)

Still, unfortunately this doesn't help greg a lot.

Greg, have you tried the solution i sent ? did it help ?

Vasco
0
 
gregasmAuthor Commented:
I must not have explained myself clearly, or else the concept is fuzzy?

If I embed the app.config file into the assembly then how will that affect the built in .net parsing of the config file?
0
 
vascovCommented:
Unfortunately i don't think the resource will be picked up at all, meaning that your config file won't be parsed.

0
 
gregasmAuthor Commented:
As I suspect, vascov. So how can I put the xml in the app.config into a different place, and tell the runtime, "hey, this isn't what you normally expect, but I want you to look here and treat this xml like the way you treat app.config"
0
 
vascovCommented:
You can specify a different config file name when creating a new app domain, but i think that it still has to be a file somewhere, which at the end of the day doesn't help much.
If you're only interested in appSettings (or your own config sections) stuff, you can use other mechanisms.
0
 
ihenryCommented:
You can have the config settings in an xml file that is embedded inside assembly. And create a dummy section in app.config just to trigger on your config handler after calling ConfigurationSettings.GetConfig( "myCustomConfig" ).

<configuration>
      <configSections>
            <section
                  name="myCustomConfig"
                  type="namespace.configHandler,assemblyName,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" />
      </configSections>
      ....
      ....
      <myCustomConfig desc="dummy config just to trigger the config handler">
      </myCustomConfig>

public class configHandler : IConfigurationSectionHandler
{
      #region ConfigurationHandlerBase Members
      public override object ProcessConfig( object parent, object configContext, XmlNode section )
      {
            section = LoadXmlFromResourceAssembly();
            ...
            ...
            // continue parsing here
      }
      #endregion
}
0
 
gregasmAuthor Commented:
Thanks vascov and ihenry.

The last posting is interesting, and I'd like to read up more on it. Can you point me to where you got this information, iHenry?
0
 
ihenryCommented:
Oops sorry, pasted wrongly. I mean this one

      #region IConfigurationSectionHandler Members
      public object Create( object parent, object configContext, XmlNode section )
      {
            section = LoadXmlFromResourceAssembly();
            ...
            ...
            // continue parsing here
      }
      #endregion
0
 
ihenryCommented:
Tell you frankly, I stole the idea from CMB :o)
0
 
ihenryCommented:
Ok, what you need to do with my suggestion is actually similar with creating a simple custom handler. But in the Create method, section parameter return value is myCustomConfig XmlNode (see my previous post) that's nothing to do with your actual configuration settings. So replace this value with XmlNode returned from a function (LoadXmlFromResourceAssembly) that gets the config settings from resource assembly.

In case you need information on how to create a custom configuraiton handler you can read this article,
Creating Custom Configuration Settings in ASP.NET
http://www.devx.com/dotnet/Article/16927/0/page/1

And to retrieve xml file from resource assembly using ResourceManager class or in CMAB you can find one internal class named Resource, it's pretty useful class to load resource from assembly (need some modification).

And something similar with my suggestion
Custom ConfigurationSettings through configuration resource embedding
http://www.codeproject.com/csharp/nemeserc.asp
0
 
vascovCommented:
iHenry, great links.
Note that thay do essentially what i posted earlier (http://www.theserverside.net/discussions/thread.tss?thread_id=25076) (wraps data in some format as a resource and then unwraps it during runtime), and still only applies to custom settings. (.NET settings like system.diagnostics, etc... will NOT be picked up).

Greg, exactly which settings are you trying to "embed" ?

Vasco
0
 
etmendzCommented:
Which all points to the fact that if you want a non-traditional .config, you can create your own schema and empower it with your own configuration parser/loader.

So far, the direction is to suggest a place to store the .config but how you access it is the same: you'll load it with your own configuration parser/loader class.

Have fun.
0
 
gregasmAuthor Commented:
I am trying to embed settings like this:

<configuration>
     <configSections>
          <section
               name="uipConfiguration"
               type="Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler,  Microsoft.ApplicationBlocks.UIProcess, Version=1.0.1.0,Culture=neutral,PublicKeyToken=null" />
    </configSections>
   
    <uipConfiguration>
        <objectTypes>
               <iViewManager
                    name="WizardViewManager"
                    type="Microsoft.ApplicationBlocks.UIProcess.WizardViewManager, Microsoft.ApplicationBlocks.UIProcess, Version=1.0.1.0,Culture=neutral,PublicKeyToken=null"
                    />
            <state ....


Those are much more complicated than

<add key="crud" value="myvalue"/>

Well at any rate, I am thinking I am gonna drop the UIP block and make my own. UIP is great, but I don't need all the features it provides... and plus, this configuration stuff is driving me cragee.
0
 
ihenryCommented:

UIP has its own configuration handler, why don't just use it?
0
 
gregasmAuthor Commented:
I am using it.

The UIP config handler is great, except that it expects the config file to be named myexe.exe.config

I want to point the config handler to either another file, or another source while still retaining the UIP config handler functionality.

Forget it. I appreciate everyone's help, but this is going nowhere.
0
 
ihenryCommented:

If you have already code that loading xml file from resource assembly, the next would be a little step, I believe. Anyway, you are giving up...
0
 
gregasmAuthor Commented:
Here is the solution to my question:

Create an xml file and embed it as a resource. In the application Main method, read the xml into an xml document, then get a reference to the xml node that contains the configuration information.

Pass the xml node to the constructor of the UIPConfigSettings object...
~Voila~.... Now I did away with the unsightly App.Config and packed it as a resource. This method would also work if I put it anywhere else, db, secure location, from a web service even... anything.

Here's the code.

---------------------------------

Private Sub LoadConfigXml()
      Try
         'Dim configFilePath As String = System.Reflection.Assembly.GetExecutingAssembly().Location & ".config"
         Dim strXml As String =Utils.GetConfigXml()
         Dim xmldoc As New Xml.XmlDocument
         xmldoc.LoadXml(strXml)
         Dim xmlNode As Xml.XmlNode = xmldoc.SelectSingleNode("/configuration/uipConfiguration")
         Microsoft.ApplicationBlocks.UIProcess.UIPConfiguration.Config = New UIPConfigSettings(xmlNode)
      Catch ex As Exception
         Throw New Exception("Could not read Config Xml", ex)
      End Try
   End Sub

   Friend Shared Function GetConfigXml() As String
      Dim strm As IO.Stream
      Dim reader As IO.StreamReader
      Try
         Dim strResource As String = "some.namespace.Config.xml"
         Dim ass As Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
         strm = ass.GetManifestResourceStream(strResource)
         reader = New IO.StreamReader(strm)

         Return reader.ReadToEnd()

      Catch ex As Exception
         Throw ex
      Finally
         If Not reader Is Nothing Then
            reader.Close()
         End If
      End Try

   End Function

0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 11
  • 6
  • 6
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now