Ya hace unos días comentaba con un compi el cambio de versión de un Assembly y si, es de lo más fácil, pero claro cuando lo usas diariamente, porque cuando dejas de usarlo, pasa lo  que pasa, jejeje… si, que las cosas se olvidan o causan duda,😀.  Con objeto de recordar un poco este tema y de aclararlo un poquito más, si es que aún no está claro, que mejor forma de hacerlo que con un ejemplo y con unas cuantas líneas de código.

El ejemplo que voy a mostrar es bastante sencillo y consta de un proyecto tipo DLL con un método y uno tipo consola para ejecutar la prueba:

1) Crear una solución “.net” con dos proyectos; Uno de tipo consola al que llamaré “CheckingAssemblyVersion”  y otro de tipo ClassLibrary (ClassLibrary1) de forma que las clase Class1 del proyecto ClassLibrary1 quede de la siguiente forma:

namespace ClassLibrary1
{
    public class Class1
    {
        public string DoSomething()
        {
            return "Something to do";
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2) En la clase Program.cs del proyecto (CheckingAssemblyVersion) invocar al método DoSomething() de Class1, para ello será necesario añadir la referencia a dicho proyecto y una vez añadido, asignar el valor “False ” a la propiedad “Copy Local”. 

3) Registrar en el GAC ClassLibrar1.dll

4) Ejecutar la aplicación y todo debería funcionar.

 

Hasta aquí todo correcto, ahora  un cambio de versión a ver que pasa:

1) Añadir un nuevo método DoSomething_2() a  Class1

2) Cambiar la versión en las propiedades del proyecto o en el fichero AssembyInfo.cs

3) Invocar al método DoSomething_2() desde el programa principal “Program.cs”.

4) Si ahora se registra la dll con la nueva versión y se ejecuta la aplicación, “zass..”

Could not load file or assembly 'ClassLibrary1, Version=2.0.0.0, Culture=neutral, PublicKeyToken=946ba4a8f00726e4' or one of its dependencies. The system cannot find the file specified.

5) Previamente hay que tener en cuenta lo siguiente:

Decir a nuestro programa que la versión a ejecutar es la 1.0.0.0 o la 2.0.0.0 y para ello:

a)  Incluir el nodo <runtime> y todo su contenido en el fichero de configuración “.config” del proyecto consola, o

b) Crear un nuevo fichero con todo este contenido, por ejemplo “PolicyVersion.config” en el mismo proyecto de la dll a la que se le pretende hacer referencia.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v2.0.50727">
      <dependentAssembly>
        <assemblyIdentity name="ClassLibrary1"
                          publicKeyToken="946ba4a8f00726e4"/>
        <!--culture="en-us" />-->
        <!-- Redirecting to version 2.0.0.0 of the assembly. -->
        <bindingRedirect oldVersion="1.0.0.0"
                         newVersion="2.0.0.0"/>
      </dependentAssembly>

    </assemblyBinding>
  </runtime>
</configuration>

Nota: El valor “v2.0.50727” del atributo “appliesTo” se refiere a la versión del Framework de .Net con el que se ha creado la dll “ClassLibrary1”

6)  Si se opta por la opción (a) y a continuación se registra de nuevo la dll en el GAC con la nueva versión todo debería funcionar sin problemas.

7)  Si se opta por la opción (b) y a continuación se registra de nuevo la dll en el GAC entonces, “zaaasssss” otra vez:

Method not found: 'System.String ClassLibrary1.Class1.DoSomethingFromConfig()'.

7.a) Ejecutar la siguiente instrucción desde el “Visual Studio Command Prompt”:

al /link:PolicyVersion.config /out:policy.2.0.0.ClassLibrary1.dll /keyfile:KeyFileTest.snk /v:1.0.0.0

Nota: a la instrucción anterior se le puede añadir el parámetro “/platform:x86” pero este dependerá de la plataforma utilizada durante la compilación.

7.b) Registrar la dll “policy.2.0.0.ClassLibrary1.dll” en el GAC.

7.c) Registrar la dll  ClassLibrary1.dll con la versión 2.0.0.0 en el GAC.

8) Todo listo, ahora la aplicación funcionará sin ningún problema.

9) En ambos casos podría desinstalarse del GAC la versión 1.0.0.0 y el sistema seguiría funcionando siempre y cuando no exista ninguna otra aplicación que la utilice.

 

He aquí dos formas de utilizar una nueva versión de una DLL sin necesidad de tener que reinstalar una y otra vez.  Esto es especialmente útil para aquellas aplicaciones que tienen que ejecutarse con con versiones específicas.

El siguiente mensaje aparecerá al intentar depurar la aplicación debido a que las dlls se encuentra instaladas en el GAC y sin ninguna copia local, OK,y listo, el inconveniente es que no puede ser depurada,😦.

 

Algunas referencias Referencias:

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

http://msdn.microsoft.com/en-us/library/dz32563a(VS.71).aspx

 

Espero haber podido aclarar alguna dudilla, ¡bueno, algo es algo!, como se suele decir, “menos da un piedra”.

Saludos desde la “Escuela Politécnica de Caceres”, concretamente desde la biblioteca ¡Que recuerdos, :-D!
Juanlu