Pregunta

Instalamos Matlab Runtime en una máquina, luego reiniciamos un servicio de ventanas .net que invoca métodos de Matlab Runtime.
El problema es que recibimos errores TypeInitializationException hasta que reiniciamos Windows. Creemos que esto sucede porque Las variables de entorno no se modifican en los servicios hasta que se reinician y Matlab usa el% Path. % variable para hacer referencia a su DLL central.
Mi pregunta es, ¿crees que puedo cambiar la variable% Path% para que Matlab la use cuando haga referencia al núcleo de DLL para su motor?
¿O es posible agregar un directorio al mecanismo de carga de DLL en tiempo de ejecución de .NET para que se haga referencia correctamente a esas dll de Matlab core sin reiniciar la máquina?

Aquí está la excepción que obtenemos

System.TypeInitializationException: The type initializer for 'MatlabCalculation.Calculation' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MathWorks.MATLAB.NET.Utility.MWMCR' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'mclmcrrt710.dll': Kan opgegeven module niet vinden. (Exception from HRESULT: 0x8007007E)
   at MathWorks.MATLAB.NET.Utility.MWMCR.mclmcrInitialize()
   at MathWorks.MATLAB.NET.Utility.MWMCR..cctor()
   --- End of inner exception stack trace ---
   at MatlabCalculation.Calculation..cctor()
   --- End of inner exception stack trace ---
   at MatlabCalculation.Calculation.Finalize()

" Kan opgegeven module niet vinden " = " El módulo especificado no encontrado "

¿Fue útil?

Solución

Si puede volver a escribir el servicio, puede usar el Sistema. Medio ambiente .GetEnvironmentVariable y SetEnvironmentVariable métodos dentro del código .NET y agregue usted mismo la ruta del motor de tiempo de ejecución de Matlab. Si no puede volver a escribir el servicio, puede intentar net stop / net start o installutil , que actúa sobre los servicios. O puede preguntar en ServerFault.

ANTIGUA RESPUESTA porque entendí mal la pregunta:

¿Se está iniciando el componente MATLAB y luego se lanza la excepción? Si es así, CTFROOT, TOOLBOXDIR y Las funciones ADDPATH pueden ayudar. Tal vez algo como:

if isdeployed
    addpath(ctfroot);
    addpath(toolboxdir('signal'));
    %more addpath(toolboxdir('toolboxname')) statements
end

Pero si MATLAB no está empezando, todo esto no ayudará.

Otros consejos

Esto podría ayudar a lo largo de tu línea de pensamiento " ¿O es posible agregar un directorio al mecanismo de carga de DLL en tiempo de ejecución de .NET para que se haga referencia a esas dll Matlab core sin reiniciar la máquina " ;:

En una aplicación, uso el siguiente código para decirle a .NET dónde encontrar los ensamblajes cuando intenta cargarlos dinámicamente. En mi caso, necesito esto ya que mi aplicación se carga como una extensión a otro programa, por lo que mis archivos DLL no están en el mismo directorio que el exe de la aplicación. Tal vez esto también se aplica a usted?

En mi caso, mi dll de aplicación principal se carga correctamente, porque está registrado para interoperabilidad COM. Pero necesito hacer lo siguiente para que MS Enterprise Library cargue sus ensamblajes, debido a la forma en que lo hace de una manera dinámica y funky. El siguiente código le dice a .NET que busque en el directorio del ensamblado que se está ejecutando actualmente cuando busca ensamblados para cargar. Podría hacer lo mismo con cualquier directorio en el que desee que se vea .NET, por ejemplo. Unos basados ??en variables de entorno.

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;

namespace CommonClasses
{
    /// <summary>
    /// Helper class to ensure the Common Language Runtime can dynamically load our referenced dlls.
    /// Because our components are called from COM via iexplore.exe the executing directory is likely to be something like 
    /// c:\program files\internet explorer\, which obviously doesn't contain our assemblies. This only seems to be a problem
    /// with the Enterprise Library so far, because it dynamically loads the assemblies it needs.
    /// This class helps by directing the CLR to use the directory of this assembly when it can't find the assembly 
    /// normally. The directory of this assembly is likely to be something like c:\program files\my program\
    /// and will contain all the dlls you could ask for.
    /// </summary>
    public static class AssemblyResolveAssistant
    {

        /// <summary>
        /// Records whether the AssemblyResolve event has been wired.
        /// </summary>
        private static bool _isWired = false;

        /// <summary>
        /// Add the handler to enable assemblies to be loaded from this assembly's directory, if it hasn't 
        /// already been added.
        /// </summary>
        public static void AddAssemblyResolveHandler()
        {
            if (!_isWired)
            {
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
                _isWired = true;
            }
        }

        /// <summary>
        /// Event handler that's called when the CLR tries to load an assembly and fails.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly result = null;
            // Get the directory where we think the assembly can be loaded from.
            string dirName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            AssemblyName assemblyName = new AssemblyName(args.Name);
            assemblyName.CodeBase = dirName;
            try
            {
                //Load the assembly from the specified path.
                result = Assembly.Load(assemblyName);
            }
            catch (Exception) { }
            //Return the loaded assembly, or null if assembly resolution failed.
            return result;
        }
    }
}

Luego llame al método AssemblyResolveAssistant.AddAssemblyResolveHandler () antes de hacer cualquier cosa que requiera la carga de ensamblajes fuera de las carpetas normales.

de: http://www.mathworks.com/support/solutions/en/data/1-A1A70V/index.html?product=MN&solution=1-A1A70V

Solución: Cuando la aplicación web llama a la función CreateEnvironmentBlock para recuperar las variables de entorno en un equipo basado en Microsoft Windows Server 2003 o basado en Microsoft Windows XP, la variable de entorno de ruta devuelta se trunca a 1,024 bytes. Este comportamiento se produce aunque el tamaño máximo de una variable de entorno es de 2.048 bytes. Este problema impide que la aplicación web obtenga la variable de entorno correcta.

Específicamente, los directorios de MATLAB Compiler Runtime en el PATH pueden haberse truncado en la variable de entorno PATH devuelta.

Para solucionar el problema, realice una de las siguientes acciones:

1) Agregue los directorios de MATLAB Compiler Runtime al comienzo de la variable PATH existente.

2) Obtenga un parche para este problema en el siguiente sitio web de Microsoft. http://support.microsoft.com/kb/906469

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top