none
actual file location of shared assemblies RRS feed

  • Question

  • hi,

    i am having trouble retrieving the actual file location of a shared assembly. I've tried assembly.location and assembly.codebase and both methods return a reference to the assembly in GAC not the installation path of the assembly.

    some more info:

    my setup file installs a few assemblies and registers them in the GAC. The purpose of finding the actual installation path and not the GAC reference is because setup is also installing content files that accompany the assemblies and these files are not located in GAC. The assemblies have methods that retrieve data from these content files so i must be able to dynamically resolve the assembly's location and access these files.

     

    help is much appreciated.

     

    Wednesday, March 24, 2010 1:43 PM

Answers

  • Ok,

    Suppose your launching a Application X (located at C:\myApp), which references assembly Y (located in the GAC).

    When your application X hits a place where it uses a type from assembly Y, it will first see if Y has already been loaded, then if it is a signed assembly it will look for it in the GAC. If Y is not found in the GAC, then it will look for the assembly in "C:\myApp" and other well known locations.

    So, in fact you are correct, assembly X knows where the application is running, but assembly Y doesn't. The problem is that you were trying to fetch location and codebase from the wrong assembly. Try getting that information from the entry assembly, which you can find with by calling:

    System.Reflection.Assembly.GetEntryAssembly()

    What you were accessing before was the executing assembly.

    For further information you can look here: http://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.71).aspx
    I know there are other resources in the msdn about this, but somehow I'm not finding them now.

    -- Blog: http://geeklyeverafter.blogspot.com/
    • Marked as answer by teodepap Wednesday, March 24, 2010 5:48 PM
    Wednesday, March 24, 2010 3:22 PM

All replies

  • When you register an assembly in the GAC, you're actually copying that assembly to a "special" folder and that's where the assembly is loaded from, so it's location will always be the GAC folder. I suspect you are deploying the dll to the GAC and to the install path, but the GAC will always be loaded first, so if you do need the install path and the assembly registered in the GAC, you'll need to find another way of finding the installation path, such as a registry key with the install path.
    -- Blog: http://geeklyeverafter.blogspot.com/
    Wednesday, March 24, 2010 1:57 PM
  • Well, that explains some things... thanks for the clarification. I suppose the question should be how does visual studio resolve the installation path and links a referenced assembly to the actual installation path rather than GAC. There is something else that is also interesting. Suppose that you develop a user control library that contains localized resources, hence the assembly is accompanied by resource files. You install that assembly to both GAC and to a user defined path and you get the following:

     

    c:\windows\assembly\UserControlLibrary.dll

    c:\program files\application\UserControlLibrary.dll

    c:\program files\application\en-GB\UserControlLibrary.Resources.dll

    c:\program files\application\it\UserControlLibrary.Resources.dll

    ... etc.

     

    If you add reference to this shared assembly in you application, that reference will link to "c:\program files\application\UserControlLibrary.dll". And of course if you localize your application the corresponding resource file will be found and used. So although it sounds logical that GAC path will be loaded first, somehow a reference to the installation folder is also maintained and the resource files are loaded. It would be nice if we new how this is done. Re-inventing the wheel is always the last option, at least for me.

     

     

     

    Wednesday, March 24, 2010 2:54 PM
  • Ok,

    Suppose your launching a Application X (located at C:\myApp), which references assembly Y (located in the GAC).

    When your application X hits a place where it uses a type from assembly Y, it will first see if Y has already been loaded, then if it is a signed assembly it will look for it in the GAC. If Y is not found in the GAC, then it will look for the assembly in "C:\myApp" and other well known locations.

    So, in fact you are correct, assembly X knows where the application is running, but assembly Y doesn't. The problem is that you were trying to fetch location and codebase from the wrong assembly. Try getting that information from the entry assembly, which you can find with by calling:

    System.Reflection.Assembly.GetEntryAssembly()

    What you were accessing before was the executing assembly.

    For further information you can look here: http://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.71).aspx
    I know there are other resources in the msdn about this, but somehow I'm not finding them now.

    -- Blog: http://geeklyeverafter.blogspot.com/
    • Marked as answer by teodepap Wednesday, March 24, 2010 5:48 PM
    Wednesday, March 24, 2010 3:22 PM
  • I think you're confusing the development environment with the runtime environment.  The dev environment doesn't care about the GAC - your references are to SDK versions of the .NET Framework.

    When you run the app, the runtime uses these rules to locate assemblies.

     http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx

    and typically if a required assembly that matches your client's description (name, assembly version, public key token, bitness etc) is in the GAC then it will be loaded from there.  The GAC is a deployment choice, not the place that Visual Studio uses for references in a dev ennvironment.


    Phil Wilson
    Wednesday, March 24, 2010 5:33 PM
  • That was half day well spent, if you think that it took me almost 10 years lot learn that much about GAC and assembly binding! lol! With you pointing in the right direction and a little bit of thinking (haven't done this for a while..) the solution was found. You see, i had tried the EntryAssembly before with no luck in getting what i was looking for. When looking for the assembly location either from the executing or the entry assembly I was always getting a reference to GAC. But your approach was clear and logical, it had to do something with the entry assembly. And then i thought about the example with the localized resources and it came to me to load the GAC referenced assembly and get it's satellite assemblies and look at their location and see where they are referenced from. And of course they are referenced at the entry assembly's location (which i already knew since i was always copying the localized resources of GAC assemblies to the application folder...), and there is where my content files have to be installed too.

     

    The pleasure of learning and solving problems is always great and much appreciated. Thanks again!

    Wednesday, March 24, 2010 5:46 PM
  • Phil, this was also helpful! Thanks for the clarification.
    Monday, March 29, 2010 2:44 PM