Загрузка DLL из Путь переменной среды из службы - PullRequest
0 голосов
/ 26 октября 2009

Мы устанавливаем Matlab Runtime на машине, затем перезапускаем службу Windows .net, которая вызывает методы из Matlab Runtime.
Проблема в том, что мы получаем ошибки TypeInitializationException, пока не перезапустим Windows. Мы думаем, что это происходит из-за того, что Переменные среды не изменяются в сервисах до перезапуска , а Matlab использует переменную% Path% для ссылки на свои основные DLL.
Мой вопрос, как вы думаете, можно ли изменить переменную% Path%, чтобы Matlab использовал ее при обращении к ядру dll для своего движка?
Или можно добавить каталог к ​​механизму загрузки DLL во время выполнения в .NET, чтобы на эти базовые библиотеки Matlab можно было правильно ссылаться без перезагрузки компьютера?

Вот исключение, которое мы получаем

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" = "Указанный модуль не найден"

Ответы [ 3 ]

1 голос
/ 27 октября 2009

Если вы можете переписать службу, вы можете использовать методы System.Environment .GetEnvironmentVariable и SetEnvironmentVariable в коде .NET и самостоятельно добавить путь к движку Matlab. Если вы не можете переписать службу, вы можете попробовать net stop / net start или installutil , которые действуют на службы. Или вы можете спросить о ServerFault.

СТАРЫЙ ОТВЕТ потому что я неправильно понял вопрос:

Компонент MATLAB запускается, а затем выдает исключение? В этом случае могут помочь функции CTFROOT, TOOLBOXDIR и ADDPATH . Может быть что-то вроде:

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

Но если MATLAB вообще не запускается, это не поможет.

0 голосов
/ 24 ноября 2009

Это может помочь вам, если вы подумаете: «Или возможно добавить каталог к ​​механизму загрузки DLL во время выполнения в .NET, чтобы на эти базовые библиотеки Matlab ссылались правильно, не перезапуская машину»:

В одном приложении я использую следующий код, чтобы сообщить .NET, где искать сборки, когда он пытается загрузить их динамически. В моем случае это нужно, так как мое приложение загружается как расширение другой программы, поэтому мои dll не находятся в той же директории, что и exe приложения. Возможно, это относится и к вам?

В моем случае моя основная программа dll загружена правильно, потому что она зарегистрирована для COM-взаимодействия. Но мне нужно сделать следующее, чтобы MS Enterprise Library загружала свои сборки из-за того, как это происходит в какой-то необычной динамичной манере. Следующий код указывает .NET искать каталог текущей исполняемой сборки при поиске сборок для загрузки. Вы можете сделать то же самое с любыми каталогами, которые вы хотите видеть в .NET, например те, которые основаны на переменных среды.

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;
        }
    }
}

Затем вызовите метод AssemblyResolveAssistant.AddAssemblyResolveHandler(), прежде чем делать что-либо, что потребует загрузки сборок вне обычных папок.

0 голосов
/ 26 октября 2009

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

Решение: Когда веб-приложение вызывает функцию CreateEnvironmentBlock для получения переменных среды на компьютере под управлением Microsoft Windows Server 2003 или Microsoft Windows XP, возвращаемая переменная среды пути усекается до 1024 байтов. Это происходит, даже если максимальный размер переменной среды составляет 2048 байт. Эта проблема не позволяет веб-приложению получить правильную переменную среды.

В частности, каталоги времени выполнения компилятора MATLAB в PATH могли быть обрезаны в возвращенной переменной среды PATH.

Чтобы обойти проблему, выполните одно из следующих действий:

1) Добавьте каталоги среды выполнения компилятора MATLAB в начале существующей переменной PATH.

2) Получите исправление для этой проблемы на следующем веб-сайте Microsoft. http://support.microsoft.com/kb/906469

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...