Carregar a DLL é de variável de ambiente PATH de um serviço
-
06-07-2019 - |
Pergunta
Nós instalar Matlab Runtime em uma máquina, então reiniciar um serviço do Windows .net que chama os métodos do Matlab Runtime.
O problema é que recebemos TypeInitializationException erros até que reinicie o Windows.
Achamos que isso acontece porque as variáveis ?? ambiente não são alteradas em serviços até reiniciar e Matlab usa o Path% % variável para fazer referência.
é núcleo de DLL
A minha pergunta é, você acha que eu posso mudar a variável% Path% para que Matlab vai usá-lo ao fazer referência a DLL do núcleo para ele do motor?
Ou é possível adicionar um diretório para o mecanismo de carregamento DLL de tempo de execução do .NET para que essas Matlab do núcleo dll seria referenciado corretamente sem reiniciar a máquina?
Aqui é a exceção chegarmos
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 módulo niet vinden" = "O módulo especificado não encontrado"
Solução
Se você pode reescrever o serviço, você pode usar o Sistema. ambiente .GetEnvironmentVariable e métodos SetEnvironmentVariable dentro do código .NET e adicionar o Matlab caminho motor runtime si mesmo. Se você não pode reescrever o serviço, você pode tentar net stop / net iniciar ou installutil , que atuam em serviços. Ou você pode perguntar sobre a ServerFault.
RESPOSTA OLD porque eu não entendi a pergunta:
é o componente MATLAB iniciar e, em seguida, lançar a exceção? Se assim for, o CTFROOT, TOOLBOXDIR, e funções Addpath pode ajudar. Talvez algo como:
if isdeployed
addpath(ctfroot);
addpath(toolboxdir('signal'));
%more addpath(toolboxdir('toolboxname')) statements
end
Mas se MATLAB não é a partir de tudo isso não vai ajudar.
Outras dicas
Isto pode ajudar ao longo de sua linha de pensamento "Ou é possível adicionar um diretório para o mecanismo de carregamento DLL de tempo de execução do .NET para que aqueles Matlab núcleo de dll seria referenciado corretamente sem reiniciar a máquina":
Em um aplicativo que use o código a seguir para dizer .NET onde encontrar assembléias quando está tentando carregá-los dinamicamente. No meu caso eu preciso isso como meu aplicativo é carregado como uma extensão para outro programa, então meus DLLs não estão no mesmo diretório que o exe aplicação. Talvez isso também se aplica a você?
No meu caso a minha principal dll aplicativo é carregado corretamente, porque está registrado para interoperabilidade COM. Mas eu preciso fazer o seguinte, a fim de MS Enterprise Library para carregar suas assembléias, por causa da maneira que ele faz que, de alguma maneira funky dinâmico. O código a seguir diz .NET para olhar no diretório do assembly atualmente em execução quando se olha para os conjuntos para carga. Você poderia fazer o mesmo com todos os diretórios que você quer .NET para olhar em, por exemplo, os baseados em variáveis ??de ambiente.
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;
}
}
}
Em seguida, chamar o AssemblyResolveAssistant.AddAssemblyResolveHandler()
método antes de fazer qualquer coisa que vai exigir o carregamento de conjuntos fora das pastas normais.
De: http://www.mathworks.com/support/solutions/en/data/1-A1A70V/index.html?product=MN&solution=1-A1A70V
Solução: Quando o aplicativo web chama a função CreateEnvironmentBlock para recuperar as variáveis ??de ambiente em um computador baseado no Microsoft Windows Server 2003 ou baseado no Microsoft Windows XP, a variável de ambiente caminho retornado será truncada para 1.024 bytes. Este comportamento ocorre mesmo que o tamanho máximo de uma variável de ambiente é 2.048 bytes. Esse problema impede a aplicação web de obter a variável de ambiente correto.
Especificamente, os diretórios MATLAB Compiler tempo de execução no caminho pode ter sido truncado na variável de ambiente PATH retornado.
Para resolver o problema, faça uma das seguintes opções:
1) Adicione os diretórios MATLAB Compiler tempo de execução no início da variável PATH existente.
2) Obter um patch para este problema no seguinte site da Microsoft. http://support.microsoft.com/kb/906469