2009-10-26 5 views
0

컴퓨터에 Matlab 런타임을 설치 한 다음 Matlab 런타임에서 메서드를 호출하는 .net Windows 서비스를 다시 시작합니다.
문제는 우리가 창을 다시 시작할 때까지 TypeInitializationException 오류가 발생한다는 것입니다. Environment Variables are not changed on services until restart 및 Matlab이 % Path % 변수를 사용하여 핵심 DLL을 참조하기 때문에 이러한 현상이 발생한다고 생각합니다.
내 질문에, 당신은 % Path 변수를 변경할 수 있다고 생각합니까? Matlab이 엔진의 핵심 dll을 참조 할 때 그것을 사용할 것입니까?
또는 .NET의 런타임 DLL 로딩 메커니즘에 디렉토리를 추가하여 컴퓨터를 다시 시작하지 않고 Matlab 코어 DLL을 올바르게 참조 할 수 있습니까? 여기 dll을 컴퓨터의 환경 변수 경로에서로드하십시오.

우리가
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() 

를 얻을 예외는 "칸 opgegeven 모듈 NIET vinden"

+0

사용자는 현재 컴퓨터를 다시 시작해야합니다. 어쩌면 나중에 제공된 답변 중 일부를 시도 할 시간이 있습니다. – pauloya

+0

더 이상 컴퓨터를 다시 시작할 필요가 없습니다. 서비스가 시작되고 Matlab DLL이 성공적으로로드되면 System.Environment.SetEnvironmentVariable()을 사용하여 Path 변수를 변경합니다. – pauloya

답변

1

, 당신은 .NET 코드 내에서 System.Environment .GetEnvironmentVariable 및 SetEnvironmentVariable 방법을 사용하고 matlab에 런타임 엔진 경로를 직접 추가 할 수 있습니다. 서비스를 다시 작성할 수없는 경우 net stop/net start 또는 서비스에 적용되는 installutil을 시도해 볼 수 있습니다. 또는 ServerFault에 대해 질문 할 수도 있습니다.

OLD 답변 내가 질문을 오해 때문에 :

는 MATLAB 구성 요소 시작 및 예외를 던지는 다음을? 그렇다면 CTFROOT, TOOLBOXDIR, and ADDPATH 함수가 도움이 될 수 있습니다. 아마도 다음과 같은 것일 수 있습니다 :

그러나 매트랩이 전혀 시작되지 않으면 도움이되지 않습니다.

+0

예외에서 나는 matlab 코드가 호출되지 않았다고 생각하고, .net 측의 솔루션을 찾고 싶습니다. matlab 코드는 변경하지 않았습니다. – pauloya

+0

우리는 matlab 런타임을 업그레이드해야했고 Path가 변경 되었기 때문에 동일한 문제가 발생했습니다. System.Environment.SetEnvironmentVariable()을 성공적으로 사용하여 종료되었습니다. 감사! – pauloya

-1

에서 = "찾을 수 없습니다 지정된 모듈"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 기반 컴퓨터에서 환경 변수를 검색합니다. eturned 경로 환경 변수가 1,024 바이트로 잘립니다. 환경 변수의 최대 크기가 2,048 바이트 경우에도이 문제가 발생합니다. 이 문제는 웹 응용 프로그램이 올바른 환경 변수를 가져 오지 못하게합니다.

특히 PATH의 MATLAB Compiler 런타임 디렉토리가 반환 된 PATH 환경 변수에서 잘릴 수 있습니다. 기존의 PATH 변수의 시작 부분에 MATLAB 컴파일러 런타임 디렉토리를 추가)

1 :

이 문제를 해결하려면 다음 중 하나를 수행합니다.

2) 다음 Microsoft 웹 사이트에서이 문제점에 대한 패치를 얻으십시오. 이 서비스를 다시 할 수 있다면 http://support.microsoft.com/kb/906469

+0

나는 이것을 전에 보았다. 이것은 우리의 경우에는 적용되지 않습니다. 우리는 % Path % 변수에 1024 바이트가 없다. 문제는 Path 변수와 관련이 있지만 잘리지 않는 것은 아닙니다. – pauloya

+0

이것은 컴퓨터를 다시 시작한 후에 모든 것이 작동하기 때문에 자신의 문제와 아무런 관련이 없습니다. –

0

이것은 생각의 길을 따라 도움이 될 수 있습니다. "또는 런타임 DLL 로딩 메커니즘에 디렉토리를 추가 할 수 있습니다.NET 그렇게 그 Matlab 코어 dll을 올바르게 컴퓨터를 다시 시작하지 않고 참조 할 수 있습니다 ":

하나의 응용 프로그램에서 나는 .NET에 어셈블리를 찾을 때 다음 코드를 사용하여 동적으로로드하려고 할 때. 제 경우에는 이 내 애플 리케이션은 다른 프로그램의 확장으로로드되므로 내 DLL은 응용 프로그램 exe와 같은 디렉토리에 있지 않습니다.

제 경우 내 주요 응용 프로그램 DLL이 올바르게로드되고, COM interop에 등록되어 있기 때문에 .NET Enterprise 라이브러리가 어셈블리를로드하기 위해서는 다음과 같은 작업을 수행해야합니다. 다음과 같은 코드는 .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()를 호출합니다.