.NET Assembly.Load/LoadFrom 如果在 windows 服务 .net 可执行文件中调用它会失败
.NET Assembly.Load/LoadFrom fails if calling it within a windows service .net executable
嗨开发者!
我目前在使用“Assembly.Load”或“Assembly.LoadFrom[=”加载特定程序集时有点迷茫86=]" 在 运行 时间内我的 WPF 应用程序中。
如果我只是 运行 可执行文件,在 运行 时间内加载程序集是可行的!
但是它抛出异常"FileNotFoundException, Could not load file or assembly .. or one of it dependencies.."
如果我使用 WPF 应用程序 运行ning 以与 windows service(在 LocalSystem 下)相同的方式加载相同的程序集。
processInstaller.Account = ServiceAccount.LocalSystem;
processInstaller.Username = null;
processInstaller.Password = null;
导致异常的程序集称为“Siemens.Sinumerik.Operate.Services.Wrapper.dll”,它被“Siemens.Sinumerik.Operate.Services.dll”引用.
-> 第 3 方程序集 - 没有可用的源代码,对我来说包装器似乎是一个混合的 cli/c++ 程序集。
现在,在对这个问题进行一些研究之后,我发现。例如,程序集的查找目录可能是 "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 或文件系统加载它(取决于第二个参数 "loadFromFile"函数 LoadAssembly)。
因此它使用 "Assembly.Load(assemblyName); // from gac"
或 "Assembly.LoadFrom(file); // from file"
我尝试解决的问题:
将动态加载的程序集引用到主项目,希望应用程序能够在启动期间将包装器程序集加载到 AppDomain -> 失败
将当前目录更改为包装程序集 dll 的存储路径 -> 失败
连接所有 AssemblyLoad 和 Resolve 事件并尝试使用 "Assembly.Load" 加载 -> fail
比较了用于服务和普通可执行文件的 AppDomains -> 似乎两者很相似,没有发现它们之间有任何特殊区别)-> 失败
使用 "fuslogvw" 获取一些可能指示任何错误的程序集绑定信息 -> 失败(请参阅下面的日志)
此外,我使用 "fuslogvw" 来找出包装器到底出了什么问题,但我没有得到任何线索,因为日志显示的结果与我只是 运行 正常可执行文件(不作为服务工作)
这是日志 "Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, 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.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.8.2.0__bdd90fa02fd1c4ee\Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Die Assembly wird im default-Load-Kontext geladen.
我希望有人可以帮助我缩小 Wrapper 程序集的加载问题 :) 或者有任何其他想法我可以做些什么..
谢谢你!
如果您需要更多信息,请告诉我!
根本原因:
该问题是由于 "LocalSystem" 帐户无法解决所有本机 dll(使用 ny 提及包装器)引起的。
要点是 Wrapper 需要设置 3 个特定路径来查找本机 dll,例如"QT" libs, .. 我在这个 "Siemens" API 的第一次安装中做了一次,但是因为安装映射了它的安装文件夹和一个额外的驱动器号,我添加了那些 3使用新创建的驱动器号的 %PATHS% 变量中的附加路径 -> 这是一个大问题导致用户 "LocalSystem" 无法访问我的?虚拟?开车 "D:"
-> 因此 %PATH% 变量中的路径不能是 "resolved",因为驱动器 "D:" 没有退出。
解决方案: 更改了 %PATH% 变量中的 3 个特定路径,以确保它现在指向 "C:.." 下的安装文件夹!
附加:
工具 "procmon" 是唯一可以看到无法解析那些原生 c/c++ 库的方法。
我在搜索时检查了工具列出的所有路径,例如"QtCore4.dll"(而 运行 作为服务)。
-> 通常:如果无法解析本机库,将使用 "Assembly.Load" 加载的 .NET 程序集不会引发任何 "AssemblyResolve" 事件。
-> Fuslogvw 无法在这个级别提供帮助,因为它没有提供有关本机库的这些详细信息。
结案:)
嗨开发者!
我目前在使用“Assembly.Load”或“Assembly.LoadFrom[=”加载特定程序集时有点迷茫86=]" 在 运行 时间内我的 WPF 应用程序中。
如果我只是 运行 可执行文件,在 运行 时间内加载程序集是可行的!
但是它抛出异常"FileNotFoundException, Could not load file or assembly .. or one of it dependencies.." 如果我使用 WPF 应用程序 运行ning 以与 windows service(在 LocalSystem 下)相同的方式加载相同的程序集。
processInstaller.Account = ServiceAccount.LocalSystem;
processInstaller.Username = null;
processInstaller.Password = null;
导致异常的程序集称为“Siemens.Sinumerik.Operate.Services.Wrapper.dll”,它被“Siemens.Sinumerik.Operate.Services.dll”引用.
-> 第 3 方程序集 - 没有可用的源代码,对我来说包装器似乎是一个混合的 cli/c++ 程序集。
现在,在对这个问题进行一些研究之后,我发现。例如,程序集的查找目录可能是 "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 或文件系统加载它(取决于第二个参数 "loadFromFile"函数 LoadAssembly)。
因此它使用 "Assembly.Load(assemblyName); // from gac"
或 "Assembly.LoadFrom(file); // from file"
我尝试解决的问题:
将动态加载的程序集引用到主项目,希望应用程序能够在启动期间将包装器程序集加载到 AppDomain -> 失败
将当前目录更改为包装程序集 dll 的存储路径 -> 失败
连接所有 AssemblyLoad 和 Resolve 事件并尝试使用 "Assembly.Load" 加载 -> fail
比较了用于服务和普通可执行文件的 AppDomains -> 似乎两者很相似,没有发现它们之间有任何特殊区别)-> 失败
使用 "fuslogvw" 获取一些可能指示任何错误的程序集绑定信息 -> 失败(请参阅下面的日志)
此外,我使用 "fuslogvw" 来找出包装器到底出了什么问题,但我没有得到任何线索,因为日志显示的结果与我只是 运行 正常可执行文件(不作为服务工作) 这是日志 "Siemens.Sinumerik.Operate.Services.Wrapper, Version=4.8.2.0, Culture=neutral, 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.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.8.2.0__bdd90fa02fd1c4ee\Siemens.Sinumerik.Operate.Services.Wrapper.dll.
LOG: Die Assembly wird im default-Load-Kontext geladen.
我希望有人可以帮助我缩小 Wrapper 程序集的加载问题 :) 或者有任何其他想法我可以做些什么..
谢谢你! 如果您需要更多信息,请告诉我!
根本原因: 该问题是由于 "LocalSystem" 帐户无法解决所有本机 dll(使用 ny 提及包装器)引起的。
要点是 Wrapper 需要设置 3 个特定路径来查找本机 dll,例如"QT" libs, .. 我在这个 "Siemens" API 的第一次安装中做了一次,但是因为安装映射了它的安装文件夹和一个额外的驱动器号,我添加了那些 3使用新创建的驱动器号的 %PATHS% 变量中的附加路径 -> 这是一个大问题导致用户 "LocalSystem" 无法访问我的?虚拟?开车 "D:" -> 因此 %PATH% 变量中的路径不能是 "resolved",因为驱动器 "D:" 没有退出。
解决方案: 更改了 %PATH% 变量中的 3 个特定路径,以确保它现在指向 "C:.." 下的安装文件夹!
附加: 工具 "procmon" 是唯一可以看到无法解析那些原生 c/c++ 库的方法。 我在搜索时检查了工具列出的所有路径,例如"QtCore4.dll"(而 运行 作为服务)。
-> 通常:如果无法解析本机库,将使用 "Assembly.Load" 加载的 .NET 程序集不会引发任何 "AssemblyResolve" 事件。
-> Fuslogvw 无法在这个级别提供帮助,因为它没有提供有关本机库的这些详细信息。
结案:)