gpt4 book ai didi

c# - Silverlight 中动态加载的程序集调用锁定文件的 DllImprot

转载 作者:行者123 更新时间:2023-11-28 06:49:10 26 4
gpt4 key购买 nike

我的 Silvelight 5 应用程序有一个非常具体的问题:我有动态加载 Silverlight 库(可能很多)的应用程序,这些库通过 dllimport 调用方法。

原因:针对不同扫描设备的应用。 Silverlight 库用于逻辑,C++ 库来自生产者并与设备连接。可能有很多 silverlight 库,它们必须在运行时加载。

问题:加载 Silverlight 库并扫描后 - 我无法使用 C++ 库访问文件。为什么我必须?如果用户尝试选择扫描仪,我会计算库的哈希码以检查服务器上是否有更新的版本。

我的实现:ViewModel 正在调用获取当前扫描器类的方法:

 using (var stream = new IsolatedStorageFileStream(scanner.DirectoryName + Path.DirectorySeparatorChar + scanner.ScannerLibraryName, System.IO.FileMode.Open, store))
{
AssemblyPart assemblyPart = new AssemblyPart();
Assembly assembly = assemblyPart.Load(stream);
return (Scanner)assembly.CreateInstance(scanner.ClassName);
}

稍后是扫描:

        this.userScanner.LoadProducerLibrary();
result = userScanner.ScanDocument();
this.userScanner.FreeProducerLibrary();

LoadProducerLibrary 调用:

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpFileName);

ScanDocument 也通过 dllimport 调用一些第三方方法。

FreeProducerLibray 调用:

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] /* unnecessary, isn't it? */
public static extern bool FreeLibrary(IntPtr hModule);

在那之后,我在不同的 View 模型中有一个方法试图打开生产者库文件来计算哈希码,但我得到“无法访问该文件,因为它正在被另一个进程使用”。

我尝试在 Scanner 类(动态加载程序集)中计算哈希码,它没问题,所以我怀疑是这个过程。但为什么 FreeLibrary 还不够呢?

你能给我一些建议吗?我应该尝试以某种方式处理 userScanner 字段吗?

最佳答案

ScanDocument calls some third part methods also via dllimport.

您遗漏了最重要的代码,但该陈述足以诊断您的问题。 pinvoke 编码器还调用 DLL 上的 LoadLibrary()。所以 DLL 的引用计数是。您的 FreeLibrary() 调用不会卸载它并且文件保持锁定状态。

您可以通过再次调用 FreeLibrary() 来解决这个问题。 卸载 DLL,但也会在您的程序中放置一颗定时炸弹。您无法安全地再次进行这些调用。 pinvoke 编码器仍然确信 DLL 已加载,因此它不会重新生成它为导入函数生成的 stub 。它们指向函数以前加载的地址,而不是现在加载的地址。它似乎 会起作用,特别是当您在人工测试中这样做时。但迟早,DLL 无法再次在同一地址重新加载,因为它的地址空间已用于其他用途,您的程序将因硬崩溃而失败。

如果你想让这个工作,那么你不能对这些方法使用 [DllImport]。您必须改为执行 pinvoke 编码器所做的工作,并为您使用的每个入口点调用 GetProcAddress(),并使用您声明的与 native 函数签名匹配的委托(delegate)使其可通过 Marshal.GetDelegateForFunctionPointer() 调用。有效,它不漂亮。

更好的选择是使用一个单独的辅助进程来进行这些调用并与之互操作。现在是安全的,让辅助进程终止确保 pinvoke stub 消失并且 DLL 被解锁。不确定 Silverlight 中的实用性,它并不是真正设计为功能列表上的进程互操作。没有 Process 类,这给方法带来了障碍。

关于c# - Silverlight 中动态加载的程序集调用锁定文件的 DllImprot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24339773/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com