Trikks

The digital adventures of Eric Herlitz

Archive for July, 2011

Programmatically check if an assembly is loaded in GAC with C#

Posted by trikks on July 13, 2011

Maybe you are writing an installer of some kind or are depending on some external assemblies to have your .net program or website to work, I often do. So with no further ado. Here is a small program which will lead you to success in these matters *fanfare*.

Example, running in console

 

Download VS project

Here

Source Code

using System;
using System.Runtime.InteropServices;

namespace ConsoleTestAssembly
{
    class Program
    {
        static void Main()
        {
            string response;

            var exist = AssemblyExist("Camelot.SharePointConnector", out response);
            Console.WriteLine(string.Concat(exist, Environment.NewLine, response, Environment.NewLine));

            exist = AssemblyExist("Camelot.SharePointIntegration", out response);
            Console.WriteLine(string.Concat(exist, Environment.NewLine, response, Environment.NewLine));

            exist = AssemblyExist("Camelot.NoExisting", out response);
            Console.WriteLine(string.Concat(exist, Environment.NewLine, response, Environment.NewLine));

            Console.ReadKey();
        }

        public static bool AssemblyExist(string assemblyname, out string response)
        {
            try
            {
                response = QueryAssemblyInfo(assemblyname);
                return true;
            }
            catch (System.IO.FileNotFoundException e)
            {
                response = e.Message;
                return false;
            }
        }

        // If assemblyName is not fully qualified, a random matching may be 
        public static String QueryAssemblyInfo(string assemblyName)
        {
            var assembyInfo = new AssemblyInfo {cchBuf = 512};
            assembyInfo.currentAssemblyPath = new String('', assembyInfo.cchBuf);

            IAssemblyCache assemblyCache;

            // Get IAssemblyCache pointer
            var hr = GacApi.CreateAssemblyCache(out assemblyCache, 0);
            if (hr == IntPtr.Zero)
            {
                hr = assemblyCache.QueryAssemblyInfo(1, assemblyName, ref assembyInfo);
                if (hr != IntPtr.Zero)
                {
                    Marshal.ThrowExceptionForHR(hr.ToInt32());
                }
            }
            else
            {
                Marshal.ThrowExceptionForHR(hr.ToInt32());
            }
            return assembyInfo.currentAssemblyPath;
        }
    }

    internal class GacApi
    {
        [DllImport("fusion.dll")]
        internal static extern IntPtr CreateAssemblyCache(
            out IAssemblyCache ppAsmCache, int reserved);
    }

    // GAC Interfaces - IAssemblyCache. As a sample, non used vtable entries 
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
    internal interface IAssemblyCache
    {
        int Dummy1();
        [PreserveSig()]
        IntPtr QueryAssemblyInfo(
            int flags,
            [MarshalAs(UnmanagedType.LPWStr)]
            String assemblyName,
            ref AssemblyInfo assemblyInfo);

        int Dummy2();
        int Dummy3();
        int Dummy4();
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct AssemblyInfo
    {
        public int cbAssemblyInfo;
        public int assemblyFlags;
        public long assemblySizeInKB;

        [MarshalAs(UnmanagedType.LPWStr)]
        public String currentAssemblyPath;

        public int cchBuf;
    }

}

Thats it.

Posted in .net, C# | Tagged: | 3 Comments »

Howto programmatically add, update and remove ConnectionStrings in Umbraco

Posted by trikks on July 13, 2011

I found that amazing no-one ever posted snippets to howto actually manipulate the web.config file when using Umbraco.

Anyway, lets keep it short.

Dont forget to import the businesslogic.dll into your project and reference it

using System;
using System.Configuration;
using umbraco; // from businesslogic.dll

 

Adding a connectionString in web.config

Note, you should either replace the Camelot.SharePointProvider with your preferred provider or add a parameter to the method to be able to modify this dynamically.

/// <summary>
/// Adds a new connectionString in web.config.
/// </summary>
/// <param name="name">Name the connection</param>
/// <param name="connString">The actual connectionstring. Read more at http://docs.bendsoft.com/camelot-net-connector/</param>
public static void AddConnection(string name, string connString)
{
    var webConfig = new ExeConfigurationFileMap { ExeConfigFilename = GlobalSettings.FullpathToRoot + "web.config" };
    var config = ConfigurationManager.OpenMappedExeConfiguration(webConfig, ConfigurationUserLevel.None);
    config.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings(name, connString, "Camelot.SharePointProvider"));
    config.Save();

    ConfigurationManager.RefreshSection("connectionStrings");
}

Updating a connectionString in web.config

Note, if the connectionString doesn’t exist this method will create it for you

/// <summary>
/// Update an existing connectionString, if it dosn't exist it will be created
/// </summary>
/// <param name="name">Name the connection</param>
/// <param name="connString">The actual connectionstring. Read more at http://docs.bendsoft.com/camelot-net-connector/</param>
public static void UpdateConnection(string name, string connString)
{
    var webConfig = new ExeConfigurationFileMap { ExeConfigFilename = GlobalSettings.FullpathToRoot + "web.config" };
    var config = ConfigurationManager.OpenMappedExeConfiguration(webConfig, ConfigurationUserLevel.None);
    var section = (ConnectionStringsSection)config.GetSection("connectionStrings");

    if (section.ConnectionStrings[name] != null)
    {
        // Update the connectionstring if it exist
        section.ConnectionStrings[name].ConnectionString = connString;
        config.Save();

        ConfigurationManager.RefreshSection("connectionStrings");
    }
    else
    {
        // ...otherwise we add a new
        AddConnection(name, connString);
    }
}

Delete a connectionString in web.config

/// <summary>
/// Remove a connectionString
/// </summary>
/// <param name="name">The name of the connectionString to remove</param>
public static void RemoveConnection(string name)
{
    var webConfig = new ExeConfigurationFileMap { ExeConfigFilename = GlobalSettings.FullpathToRoot + "web.config" };
    var config = ConfigurationManager.OpenMappedExeConfiguration(webConfig, ConfigurationUserLevel.None);
    var section = (ConnectionStringsSection)config.GetSection("connectionStrings");

    // Die if the connectionstring dosn't exist
    if (section.ConnectionStrings[name] == null) return;

    var keys = section.ConnectionStrings;
    keys.Remove(name);
    config.Save();
    ConfigurationManager.RefreshSection("connectionStrings");
}

Check if connectionstring exist

/// <summary>
/// Check if a connectionString with the same name already exist
/// </summary>
/// <param name="name">Name of the connection</param>
/// <returns>True on existence, otherwise false</returns>
private static bool ConnectionExist(string name)
{
    var webConfig = new ExeConfigurationFileMap { ExeConfigFilename = GlobalSettings.FullpathToRoot + "web.config" };
    var config = ConfigurationManager.OpenMappedExeConfiguration(webConfig, ConfigurationUserLevel.None);
    var section = (ConnectionStringsSection)config.GetSection("connectionStrings");

    // Return false if it doesn't exist, true if it does
    return section.ConnectionStrings[name] != null;
}

Thats it!

Posted in Umbraco | 1 Comment »

 
Follow

Get every new post delivered to your Inbox.