Search code examples
winformsdevexpressmefgac

Why is this DLL DevExpress.ExpressApp loading?


I am trying to deploy a plugin to a customer. We use MEF, import, export attributes. I use the Export and the client imports it My application uses DevExpress XtraGrid, XtraEditors and many other DevExpress DLL's(see screenshot), System.Data.Services. Inspite of providing all these required DLL's and many of their dependencies, the plugin still seems to be requiring DevExpress.ExpressApp. DevExpress.ExpressApp and all its other dependencies are definitely not needed.

Since the client kept complaining that they have a FileNotFound exception, I decided to make a test project to import my own plugin. This is my test code to test the clients theory that he is getting is the following.

System.IO.FileNotFoundException: Could not load file or assembly 'DevExpress.ExpressApp.v14.2, Version=14.2.7.0, 


Our Plugin
     [Export(typeof (ISomething))]
        public class MyClass : ISomething
        {

    }
TESTER
     class Program
    {
           [ImportMany]
        public IEnumerable<ISomething> Somethings { get; set; }
        static void Main(string[] args)
        {

            var rp = new Program();
            rp.Run();


        }
        public void Run()
        {
            Compose();

        }
        public void Compose()
        {
            try
            {
                AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;
                AggregateCatalog aggregatecatalogue = new AggregateCatalog();
                aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
                CompositionContainer container = new CompositionContainer(aggregatecatalogue);
                CompositionBatch batch = new CompositionBatch();
                batch.AddPart(this);
                container.Compose(batch);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
        {
            System.Text.StringBuilder msg = new System.Text.StringBuilder();
            msg.AppendLine(e.Exception.GetType().FullName);
            msg.AppendLine(e.Exception.Message);
            System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
            msg.AppendLine(st.ToString());
            msg.AppendLine();
            String desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string logFilePath = String.Format("{0}\\{1}", desktopPath, "logfile.txt");
            System.IO.File.AppendAllText(logFilePath, msg.ToString());

        }

Sure enough, I saw in the output window and found out that it was indeed loading this DLL and some of the dependencies related to ExpressApp from GAC. Question: How do I figure out where and why is ExpressApp needed? I can simply just deliver the DLL but then it goes on and on about a TON of dependencies which I have clue why they would be needed.

enter image description here


Solution

  • there are tools for checking managed assembly dependencies. The MS Windows SDK contains the ildasm.exe utility. Chances are you already have it installed in:

    C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\ildasm.exe

    When I had a similar problem (it was dll version mismatch) I have also used cygwin's 'grep' from command line to search for the missing dependency string across all DX and our custom assemblies to locate the actual .dll file referencing the missing dependency dll version. Then opened it in ildasm.exe and double clicked on the MANIFEST tree node. There I've seen the reference to the .dll version I didn't have.

    You may follow the same steps to try to track the missing dependency. Run the "DevExpress.ExpressApp" string search against all DX dlls in your project's bin directory then if result is found, open the reported file with ildasm.exe

    Note, most probably you don't have 'grep' from the https://www.cygwin.com/ package installed, so use the string search utility which is available to you.

    There are also other 3rd party tools for checking dll dependencies but those have to be installed separately, while ildasm.exe is a part of Windows SDK. See this question's answers for other tools refs:

    How do I determine the dependencies of a .NET application?

    UPDATE:

    if you don't have all your DX libs in the bin folder because your app is a plugin and uses DX libs directly from GAC, then you may search for DevExpress.ExpressApp references right in the DX installation folder, in my case:

    C:\Program Files (x86)\DevExpress 15.2\Components\Bin\Framework

    I've copied the above folder contents to a temp folder, removed all locale subfolders as well as all DevExpress.ExpressApp.* dlls and then ran a command:

    grep -nr "DevExpress.ExpressApp"
    

    which produced the following results:

    Binary file DevExpress.EasyTest.v15.2.dll matches
    Binary file DevExpress.Persistent.Base.v15.2.dll matches
    Binary file DevExpress.Persistent.BaseImpl.EF.v15.2.dll matches
    Binary file DevExpress.Persistent.BaseImpl.v15.2.dll matches
    Binary file DevExpress.Workflow.Activities.v15.2.Design.dll matches
    Binary file DevExpress.Workflow.Activities.v15.2.dll matches
    

    See if any of the above dlls is used by either your plugin or the host app where the plugin is to be deployed.

    HTH