如果在Windows服务.net可执行文件

时间:2019-12-13 11:57:24

标签: .net wpf windows-services .net-assembly

嗨,开发者们!

我目前在运行时在WPF应用程序中使用“ Assembly.Load ”或“ Assembly.LoadFrom ”加载特定的程序集时有些迷惑。

如果我只是运行可执行文件,则可以在运行时加载程序集!

但是但它引发异常“ FileNotFoundException,无法加载文件或程序集..或其中一个依赖项。”  如果我以 windows服务(在LocalSystem下)运行的WPF应用程序以相同的方式加载相同的程序集。

processInstaller.Account = ServiceAccount.LocalSystem;
processInstaller.Username = null;
processInstaller.Password = null;

引起异常的程序集称为“ Siemens.Sinumerik.Operate.Services.Wrapper.dll ”,该引用由“ Siemens.Sinumerik.Operate.Services.dll ”。

->第三方程序集-没有可用的源,对我而言,包装器似乎是cli / c ++混合程序集。

现在,对这个问题进行了一些研究之后,我发现.e.g可能是程序集的查找目录是“ C:\ windows \ system32”,而不是可存储可执行文件的文件夹。或采用“ fuslogvw”来缩小问题范围。

但是,这不是我的第一个项目在运行时加载程序集进行某些执行。唯一的事情是我在运行时从未加载过混合的“ cli / c ++”程序集 ->可能存在任何已知问题,或者可能无法正确加载“ cli / c ++”程序集?

这是我用来从文件或gac加载程序集的代码

LoadAssembly("Siemens.Sinumerik.Operate.Services"); // this assembly references the wrapper
LoadAssembly("Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, PublicKeyToken=bdd90fa02fd1c4ee", false); // load the wrapper from GAC using AssemblyName -> Exception only in service
LoadAssembly("Siemens.Sinumerik.Operate.Services.Wrapper"); // load the wrapper from file using AssemblyName -> Exception only in service

LoadAssembly 正在检查AssemblyName是否已在当前AppDomain中加载,如果没有,则使用GAC或FileSystem加载它(取决于LoadAssembly函数的第二个参数“ loadFromFile”)。

因此它使用"Assembly.Load(assemblyName); // from gac""Assembly.LoadFrom(file); // from file"

我已尝试解决的问题:

  • 将动态加载的程序集引用到主项目,希望应用程序能够在启动过程中将包装程序程序集加载到AppDomain中-> 失败

  • 将当前目录更改为包装程序集dll的存储路径-> 失败

  • 启动所有AssemblyLoad和Resolve事件,并尝试使用“ Assembly.Load”加载-> 失败

  • 比较了用于该服务和正常的可执行文件的AppDomain->看起来都不错,因为两者之间没有任何特殊区别)-> 失败

  • 使用“ fuslogvw”获取一些可能表示任何错误的程序集绑定信息-> 失败(请参见下面的日志)

另外,我使用“ fuslogvw”来找出包装器到底出了什么问题,但是我没有任何线索,因为日志显示的结果与我只运行普通可执行文件的结果相同(不能作为服务运行) 这是日志“ Siemens.Sinumerik.Operate.Services.Wrapper,版本= 4.8.2.0,区域性=中性,PublicKeyToken = bdd90fa02fd1c4ee.HTM”

*** Protokolleintrag für Assembly-Binder  (13.12.2019 @ 12:12:21) ***

Der Vorgang wurde durchgeführt.
Ergebnis der Bindung: hr = 0x0. Der Vorgang wurde erfolgreich beendet.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt.  C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\MTF.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, PublicKeyToken=bdd90fa02fd1c4ee
 (Fully-specified)
LOG: Appbase = file:///C:/Projekte/MTF/trunk/MTFMain/MTF/bin/Debug/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = MTF.exe
Aufruf von Assembly : MTF, Version=2.0.7286.21871, Culture=neutral, PublicKeyToken=null.
===
LOG: Diese Bindung startet im default-Load-Kontext.
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\MTF.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, PublicKeyToken=bdd90fa02fd1c4ee
LOG: Die Assembly wurde bei Suche im GAC gefunden.
LOG: Die Bindung war erfolgreich. Assembly wird zurückgegeben von C:\Windows\assembly\GAC_32\Siemens.Sinumerik.Operate.Services.Wrapper\4.8.2.0__bdd90fa02fd1c4ee\Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Die Assembly wird im default-Load-Kontext geladen.

这里是“ WhereRefBind!Host =(LocalMachine)!FileName =(Siemens.Sinumerik.Operate.Services.Wrapper.dll).HTM ”:

*** Protokolleintrag für Assembly-Binder  (13.12.2019 @ 12:14:00) ***

Der Vorgang wurde durchgeführt.
Ergebnis der Bindung: hr = 0x0. Der Vorgang wurde erfolgreich beendet.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt.  C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\MTF.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: Where-ref-Bindung. Speicherort = C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\dll\Siemens.Sinumerik.Operate.Services.Wrapper.dll
LOG: Appbase = file:///C:/Projekte/MTF/trunk/MTFMain/MTF/bin/Debug/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = MTF.exe
Aufruf von Assembly : (Unknown).
===
LOG: Diese Bindung startet im LoadFrom-Load-Kontext.
WRN: Das native Image wird nicht im LoadFrom-Kontext durchsucht. Das native Image wird nur im Standard-Load-Kontext durchsucht, z. B. Assembly.Load().
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\MTF.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config wird verwendet.
LOG: Download von neuem URL file:///C:/Projekte/MTF/trunk/MTFMain/MTF/bin/Debug/dll/Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Der Assembly-Download wurde durchgeführt. Datei-Setup wird begonnen: C:\Projekte\MTF\trunk\MTFMain\MTF\bin\Debug\dll\Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Die von der Quelle ausgeführte Setup-Phase beginnt.
LOG: Der Assemblyname ist: Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, PublicKeyToken=bdd90fa02fd1c4ee.
LOG: Die Richtlinie wird für where-ref-Bindung erneut angewendet.
LOG: Verweis nach der Richtlinie: Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, PublicKeyToken=bdd90fa02fd1c4ee
LOG: Die Assembly wurde bei Suche im GAC gefunden.
LOG: Wechseln vom LoadFrom-Kontext zum Standardkontext.
LOG: Die Bindung war erfolgreich. Assembly wird zurückgegeben von C:\Windows\assembly\GAC_32\Siemens.Sinumerik.Operate.Services.Wrapper\4.8.2.0__bdd90fa02fd1c4ee\Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Die Assembly wird im default-Load-Kontext geladen.

我希望有人可以帮助我缩小Wrapper程序集的加载问题:)或对我还有其他想法。.

到目前为止,谢谢!! 让我知道您是否需要更多信息!

1 个答案:

答案 0 :(得分:0)

根本原因: 该问题是由于并非所有本地dll(用于提及包装程序的dll)都可以为“ LocalSystem”帐户解决的。

要点是包装器希望设置3条特定路径来查找本机dll,例如“ QT”库,..我在“ Siemens” API的首次安装中进行了一次安装,但是由于该安装使用附加的驱动器号映射其安装文件夹,因此我在%PATHS%变量中添加了这3个附加路径使用新创建的驱动器号->这是一个大问题,因为用户“ LocalSystem”无权访问我的“虚拟”用户?驱动器“ D:” ->因此,由于驱动器“ D:”没有退出,因此无法“解析”%PATH%变量中的路径。

解决方案::更改了%PATH%变量中的3条特定路径,以确保它现在指向“ C:..”下的安装文件夹!

附加: 工具“ procmon”是查看无法解析这些本地c / c ++库的唯一方法。 我在搜索例如时检查了列出的工具的所有路径“ QtCore4.dll”(作为服务运行时)。

->通常:如果无法解析本机库,则用“ Assembly.Load”加载的.NET程序集将不会引发任何“ AssemblyResolve”事件。

-> Fuslogvw在此级别上无济于事,因为它没有提供这些有关本机库的详细信息。

关闭案例:)