<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Luis Guerrero &#187; Azure</title>
	<atom:link href="http://luisguerrero.net/blog/category/azure/feed/" rel="self" type="application/rss+xml" />
	<link>http://luisguerrero.net</link>
	<description>Hablando de .NET, Silverlight, WPF, Windows Phone 7 y depuración</description>
	<lastBuildDate>Tue, 31 Jan 2012 19:55:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Ejecutar tareas elevadas durante el ciclo de vida del Rol de Azure</title>
		<link>http://luisguerrero.net/blog/2011/04/29/ejecutar-tareas-elevadas-durante-el-ciclo-de-vida-del-rol-de-azure/</link>
		<comments>http://luisguerrero.net/blog/2011/04/29/ejecutar-tareas-elevadas-durante-el-ciclo-de-vida-del-rol-de-azure/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 10:28:14 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://luisguerrero.net/blog/2011/04/29/ejecutar-tareas-elevadas-durante-el-ciclo-de-vida-del-rol-de-azure/</guid>
		<description><![CDATA[Cuando desarrollamos para Windows Azure podemos encontrarnos con distintos escenarios que van desde aplicaciones completamente .NET y aplicaciones que son migraciones de aplicaciones existentes. En ese sentido uno de los dolores de cabeza a la hora de trabajar con Azure son los registros de componentes COM durante el arranque del rol de Azure. Este tipo [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando desarrollamos para Windows Azure podemos encontrarnos con distintos escenarios que van desde aplicaciones completamente .NET y aplicaciones que son migraciones de aplicaciones existentes. En ese sentido uno de los dolores de cabeza a la hora de trabajar con Azure son los registros de componentes COM durante el arranque del rol de Azure. Este tipo de problema se soluciona normalmente creando una tarea en el startup del rol que desea consumir ese tipo de componentes COM.</p>
<p>Si por ejemplo nosotros durante el ciclo de ejecución de nuestro rol queremos ejecutar un proceso con elevación, es decir con permisos completos de administrador no podemos hacerlo porque el proceso que hostea la web y el worker role no está elevado, y aunque nosotros lo indiquemos a la hora de ejecutar el proceso eso no va a funcionar.</p>
<p>Es por eso que podemos hacer un pequeño truco para que podamos ejecutar proceso elevados durante nuestro ciclo de ejecución del rol, es decir en cualquier momento, así podemos registrar componentes COM, o llamar a ejecutables del SO de manera mucho más cómoda. Para poder llegar a esa aproximación tenemos que buscar un entorno donde podamos ejecutar nuestras aplicaciones de manera elevada, y ese entorno es el entorno de startup del rol, así que de alguna manera lo que tenemos que tener es un proceso sentinel que se arranque en el startup del rol y que acepte peticiones para ejecutar procesos de manera elevada.</p>
<p>Pues justamente eso es lo que vamos a hacer, utilizando WCF para abrir un pipe de comunicación entre los procesos vamos a crear un servicio que escuche peticiones de otro proceso a través de un pipe para enviar un mensaje que representa una invocación de un proceso.</p>
<p>Vamos por pasos:</p>
<h3>Definición del servicio</h3>
<p>Como lo que queremos hacer es exponer un servicio de WCF a través de pipes de Windows, tenemos que definir la interfaz del contrato de operaciones:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">[ServiceContract(Namespace = <span style="color: #006080">&quot;http://azure.plainconcepts.com/schemas/04/2011/azure/executionhost&quot;</span>)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> IExecutionHost
{
    [OperationContract]
    <span style="color: #0000ff">void</span> ExecuteTask(ProcessTask host);
}</pre>
</div>
<p>Una vez que tenemos definido el contrato servicio tenemos que hacer dos cosas, primero hacer la implementación del servicio, es decir el proceso sentinel que escuchará las peticiones recibidas y hará el trabajo de ejecutar esos procesos.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ExecutionHostService : IExecutionHost
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> ExecuteTask(ProcessTask host)
    {
        Process process = <span style="color: #0000ff">new</span> Process();
        process.StartInfo = host.StartInfo;
        process.Start();
    }
}</pre>
</div>
<p>Otra cosa que tenemos que hacer en el proceso sentinel es hostear el servicio y ponerlo a escuchar peticiones a través del binding que nosotros seleccionemos, en este caso NetNamedPipeBinding:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ExecutionHostServiceManager
{
    <span style="color: #0000ff">public</span> ExecutionHostServiceManager()
    {
        service = <span style="color: #0000ff">new</span> ExecutionHostService();
        ServiceHost host = <span style="color: #0000ff">new</span> ServiceHost(service);

        <span style="color: #0000ff">string</span> address = <span style="color: #006080">&quot;net.pipe://PlainConcepts/Azure/ExecutionHost&quot;</span>;
        NetNamedPipeBinding binding = <span style="color: #0000ff">new</span> NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
        host.AddServiceEndpoint(<span style="color: #0000ff">typeof</span>(IExecutionHost), binding, address);

        <span style="color: #008000">// Add a mex endpoint</span>
        <span style="color: #0000ff">long</span> maxBufferPoolSize = binding.MaxBufferPoolSize;

        <span style="color: #0000ff">int</span> maxBufferSize = binding.MaxBufferSize;

        <span style="color: #0000ff">int</span> maxConnections = binding.MaxConnections;

        <span style="color: #0000ff">long</span> maxReceivedMessageSize =
            binding.MaxReceivedMessageSize;

        NetNamedPipeSecurity security = binding.Security;

        <span style="color: #0000ff">string</span> scheme = binding.Scheme;

        XmlDictionaryReaderQuotas readerQuotas =
            binding.ReaderQuotas;

        BindingElementCollection bCollection = binding.CreateBindingElements();

        HostNameComparisonMode hostNameComparisonMode =
            binding.HostNameComparisonMode;

        <span style="color: #0000ff">bool</span> TransactionFlow = binding.TransactionFlow;

        TransactionProtocol transactionProtocol =
            binding.TransactionProtocol;

        EnvelopeVersion envelopeVersion =
            binding.EnvelopeVersion;

        TransferMode transferMode =
            binding.TransferMode;
        host.Open();
    }

    <span style="color: #0000ff">private</span> ExecutionHostService service;
}</pre>
</div>
<p>Todo ello lo tenemos que poner en un pequeño programa de consola que será el proceso en sí que hosteará el pipe de Windows que aceptará peticiones a través de WCF:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">class</span> Program
{
    <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[] args)
    {
        <span style="color: #0000ff">new</span> ExecutionHostServiceManager();
        Thread.Sleep(Timeout.Infinite);
    }
}</pre>
</div>
<p>Fijaros que al final de la ejecución de la clase hay un Thread.Sleep(Timeout.Infinite) que nos permite esperar eternamente en el proceso para que así el proceso esté disponible durante todo el ciclo de vida del rol, permitiéndonos ejecutar un proceso elevado en cualquier momento.</p>
<h3>Haciendo llamadas al servicio</h3>
<p>Como bien es sabido para poder hacer llamadas a un servicio de WCF lo primero que tenemos que hacer es generar un proxy en el cliente para hacer esas llamadas. Como queremos hacerlo todo por código para simplificar, lo que vamos a hacer es una clase que herede de ClientBase&lt;T&gt; siendo T la interfaz del contrato de operaciones de nuestro servicio.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ExecutionHostClient : ClientBase&lt;IExecutionHost&gt;
{
    <span style="color: #0000ff">static</span> ExecutionHostClient()
    {
        <span style="color: #0000ff">string</span> address = <span style="color: #006080">&quot;net.pipe://PlainConcepts/Azure/ExecutionHost&quot;</span>;
        NetNamedPipeBinding binding = <span style="color: #0000ff">new</span> NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
        binding.CloseTimeout = TimeSpan.MaxValue;
        binding.ReceiveTimeout = TimeSpan.MaxValue;
        binding.SendTimeout = TimeSpan.MaxValue;
        EndpointAddress endpoint = <span style="color: #0000ff">new</span> EndpointAddress(address);
        client = <span style="color: #0000ff">new</span> ExecutionHostClient(binding, endpoint);
    }

    <span style="color: #0000ff">public</span> ExecutionHostClient(Binding binding, EndpointAddress remoteAddress) :
        <span style="color: #0000ff">base</span>(binding, remoteAddress)
    {
    }

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> ExecuteTask(ProcessTask task)
    {
        Channel.ExecuteTask(task);
    }

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> ExecuteRemoteTask(ProcessTask task)
    {
        client.ExecuteTask(task);
    }

    <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> ExecutionHostClient client;
}</pre>
</div>
<p>Es importante que el proxy se inicialice con el mismo binding que el de servidor para que las invocaciones funcionen. En este ejemplo para simplificar tenemos una referencia estatica del proxy y solamente lo exponemos a través de un método estático.</p>
<h3>Invocando servicios </h3>
<p>Para el ejemplo actual podemos registrar los componentes COM de una carpeta que tengamos en nuestro worker role:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> RegisterComHelper
    {
        <span style="color: #0000ff">public</span> RegisterComHelper()
        {

        }

        <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Register()
        {
            <span style="color: #008000">// hay que buscar la localizacion en el servidor de azure de donde estan los ensamblados</span>
            <span style="color: #008000">// como no sabemos donde estan los ficheros tenemos que buscar el modulo </span>
            <span style="color: #008000">// Habitania.RegisterCom.dll que es especifico para este ejemplo</span>
            <span style="color: #008000">// así nos aseguramos que estamos buscando la dll correcta</span>
            Process current = Process.GetCurrentProcess();
            var found = (from p <span style="color: #0000ff">in</span> current.Modules.Cast&lt;ProcessModule&gt;().ToList()
                         <span style="color: #0000ff">where</span> p.ModuleName == <span style="color: #006080">&quot;PlainConcepts.Azure.WorkerRoleDemo.dll&quot;</span>
                         select p).FirstOrDefault();

            <span style="color: #0000ff">if</span> (found != <span style="color: #0000ff">null</span>)
            {
                <span style="color: #008000">// a partir de la locacion del modulo cargada por el proceso </span>
                <span style="color: #008000">// somos capaces de encontrar la informacion del directorio y buscar</span>
                <span style="color: #008000">// la carpeta dlls que contiene la lista de dlls que queremos registar</span>
                <span style="color: #0000ff">string</span> directoryLocation = Path.GetDirectoryName(found.FileName);

                <span style="color: #0000ff">string</span> dllPath = Path.Combine(directoryLocation, <span style="color: #006080">&quot;V3COM30&quot;</span>);

                <span style="color: #0000ff">string</span>[] files = Directory.GetFiles(dllPath);

                <span style="color: #0000ff">foreach</span> (var item <span style="color: #0000ff">in</span> files)
                {
                    <span style="color: #0000ff">if</span> (item.EndsWith(<span style="color: #006080">&quot;.dll&quot;</span>))
                        RegisterComObject(item);
                }

                dllPath = Path.Combine(directoryLocation, <span style="color: #006080">&quot;V3COM&quot;</span>);

                files = Directory.GetFiles(dllPath);

                <span style="color: #0000ff">foreach</span> (var item <span style="color: #0000ff">in</span> files)
                {
                    <span style="color: #0000ff">if</span> (item.EndsWith(<span style="color: #006080">&quot;.dll&quot;</span>))
                        RegisterComObject(item);
                }
            }
        }

        <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> RegisterComObject(<span style="color: #0000ff">string</span> filePath)
        {
            ProcessStartInfo info = <span style="color: #0000ff">new</span> ProcessStartInfo();
            info.FileName = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.System),
                <span style="color: #006080">&quot;regsvr32.exe&quot;</span>);
            info.Arguments = <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">&quot;/i {0}&quot;</span>, filePath);
            info.UseShellExecute = <span style="color: #0000ff">false</span>;

            ExecutionHostClient.ExecuteRemoteTask(<span style="color: #0000ff">new</span> ProcessTask()
            {
                StartInfo = info
            });
        }
    }</pre>
</div>
<p>Este método para trabajar con Windows Azure puede ser un poco complicado de montar, pero una vez hecho tenemos un mecanismo muy sencillo para hacer cosas más complicadas como por ejemplo ejecutar otro tipo de tareas de mantenimiento directamente desde ahí.</p>
<p>El codigo completo del ejemplo <a href="http://www.luisguerrero.net/downloads/ExecuteProcessElevated.zip">aquí</a>.</p>
<p>Luis Guerrero.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2011/04/29/ejecutar-tareas-elevadas-durante-el-ciclo-de-vida-del-rol-de-azure/feed/</wfw:commentRss>
		<slash:comments>3065</slash:comments>
		</item>
		<item>
		<title>El worker role de Azure lanza un FileNotFoundException al cargar</title>
		<link>http://luisguerrero.net/blog/2010/05/11/el-worker-role-de-azure-lanza-un-filenotfoundexception-al-cargar/</link>
		<comments>http://luisguerrero.net/blog/2010/05/11/el-worker-role-de-azure-lanza-un-filenotfoundexception-al-cargar/#comments</comments>
		<pubDate>Tue, 11 May 2010 10:41:25 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Depuración]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=f36b5da6-c787-42c6-bc39-d1750cb7bf5e</guid>
		<description><![CDATA[Actualmente estoy trabajando en un player con tecnología de smooth streaming basado en Silverlight y tenemos algunos servicios que el player consume que queremos publicar en Azure. El caso es que me he puesto a hacer las primeras pruebas en Azure en mi maquina local, pero cada vez que ejecuto el projecto el Azure Simulation [...]]]></description>
			<content:encoded><![CDATA[<p>Actualmente estoy trabajando en un player con tecnología de smooth streaming basado en Silverlight y tenemos algunos servicios que el player consume que queremos publicar en Azure. El caso es que me he puesto a hacer las primeras pruebas en Azure en mi maquina local, pero cada vez que ejecuto el projecto el Azure Simulation Environment este me lanza un FileLoadException.</p>
<div style="line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: gray 1px solid; padding: 4px;">
<pre style="line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas, 'Courier New', courier, monospace; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">[runtime] Role entrypoint could not be created:
System.IO.FileLoadException: Could not load file or assembly <span style="color: #006080;">'Microsoft.Silverlight.MediaPlayer.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a10dc7bdece43c5c'</span> or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
File name: <span style="color: #006080;">'Microsoft.Silverlight.MediaPlayer.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a10dc7bdece43c5c'</span> ---&gt; System.IO.FileLoadException: Could not load file or assembly <span style="color: #006080;">'file:///C:\Plain\Microsoft.SmoothPlayer\Source\Azure\Microsoft.Silverlight.MediaPlayer.Online\bin\Debug\Microsoft.Silverlight.MediaPlayer.Online.csx\roles\Microsoft.Silverlight.MediaPlayer.Web\approot\bin\Microsoft.Silverlight.MediaPlayer.Web.dll'</span> or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
File name: <span style="color: #006080;">'file:///C:\Plain\Microsoft.SmoothPlayer\Source\Azure\Microsoft.Silverlight.MediaPlayer.Online\bin\Debug\Microsoft.Silverlight.MediaPlayer.Online.csx\roles\Microsoft.Silverlight.MediaPlayer.Web\approot\bin\Microsoft.Silverlight.MediaPlayer.Web.dll'</span>

WRN: Assembly binding logging <span style="color: #0000ff;">is</span> turned OFF.
To enable assembly bind failure logging, set the registry <span style="color: #0000ff;">value</span> [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There <span style="color: #0000ff;">is</span> some performance penalty associated with assembly bind failure logging.
To turn <span style="color: #0000ff;">this</span> feature off, remove the registry <span style="color: #0000ff;">value</span> [HKLM\Software\Microsoft\Fusion!EnableLog].

   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark&amp; stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark&amp; stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CreateRoleEntryPoint(RoleType roleTypeEnum)
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum)</pre>
</div>
<p>Llegado a este punto hice una doble comprobación de que realmente el fichero estaba ahi y se tenian permisos para leer el fichero. Active la salida del Fusion Log para ver los errores de carga de los ensamblados pero no me aparecía nada. Así que decidí utilizar el WinDBG para sacar un poco más de información.</p>
<p>Me atache al proceso host de web de Azure WaWebHost.exe (Microsoft Windows Azure Web Host), cargue todos los símbolos y SOS. El primer comando que ejecute fue !threads y encontré esto:</p>
<div style="line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: gray 1px solid; padding: 4px;">
<pre style="line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas, 'Courier New', courier, monospace; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">0:000&gt; !threads
ThreadCount: 6
UnstartedThread: 0
BackgroundThread: 5
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
                                              PreEmptive                                                Lock
       ID OSID        ThreadOBJ     State   GC     GC Alloc Context                  Domain           Count APT Exception
XXXX    1 1ba0 000000000014c4a0   2008220 Enabled  00000000053a1c10:00000000053a1fd0 0000000002f182a0     1 Ukn System.IO.PathTooLongException (0000000005305a80)
XXXX    2  294 00000000000e46d0      b220 Enabled  00000000053d09f8:00000000053d1fd0 0000000002f17990     0 MTA (Finalizer)
XXXX    3 13b0 00000000022f9350   a802220 Enabled  0000000000000000:0000000000000000 0000000002f17990     0 MTA (Threadpool Completion Port)
XXXX    4 1a80 0000000002fbc080    80a220 Enabled  0000000000000000:0000000000000000 0000000002f17990     0 MTA (Threadpool Completion Port)
XXXX    5 1ae0 0000000002fbe650      1220 Enabled  0000000000000000:0000000000000000 0000000002f17990     0 Ukn
   0    6  7e4 0000000002fe22c0      1020 Enabled  00000000053c69b0:00000000053c7fd0 0000000002f182a0     0 Ukn System.IO.FileLoadException (00000000053a7ca8)</pre>
</div>
<p>Como se puede observer hay dos dominios de aplicación cargados en el proceso, el thread 1 y 6 están ejecutando código de ese dominio de aplicación y el thread 1 muestra la excepción que estamos depurando FileLoadException pero el thread 6 muestra un System.IO.PathTooLongException.</p>
<div style="line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: gray 1px solid; padding: 4px;">
<pre style="line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas, 'Courier New', courier, monospace; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">0:001&gt; !pe 0000000005305a80
Exception <span style="color: #0000ff;">object</span>: 0000000005305a80
Exception type: System.IO.PathTooLongException
Message: The specified path, file name, or both are too <span style="color: #0000ff;">long</span>. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
InnerException: &lt;none&gt;
StackTrace (generated):
    SP               IP               Function
    00000000031BD360 000007FEED2D5A8F mscorlib_ni!System.IO.Path.NormalizePathFast(System.String, Boolean)+0xd0f
    00000000031BD420 000007FEED239CA6 mscorlib_ni!System.IO.File.Exists(System.String)+0x96

StackTraceString: &lt;none&gt;
HResult: 800700ce
The current thread <span style="color: #0000ff;">is</span> unmanaged</pre>
</div>
<p>Así que el único problema es que el path del fichero es demasiado largo y el sistema no puede cargarlo.</p>
<p>Espero que os sea de ayuda!</p>
<p>Luis Guerrero.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2010/05/11/el-worker-role-de-azure-lanza-un-filenotfoundexception-al-cargar/feed/</wfw:commentRss>
		<slash:comments>3118</slash:comments>
		</item>
	</channel>
</rss>

