如何让LabView停止锁定我的.NET DLL

本文关键字:锁定 我的 NET DLL LabView | 更新日期: 2023-09-27 18:20:05

我正在试用LabView,尝试如何将其与.NET结合使用。我已经成功创建了一个小型应用程序,它可以读取仪表,在.NET中转换值,并在另一个仪表上显示结果。

问题是,当我试图添加到.NET项目并重建时,DLL被锁定,我无法覆盖它。NI声称LabView使用了卷影复制。但如果这是真的,我的DLL就不应该被锁定。

有没有办法让LabView停止锁定DLL?除了每次我想重建时都退出LabView之外,这似乎是一个乏味的修复。

如何让LabView停止锁定我的.NET DLL

我认为您的应用程序中发生的情况如下:

当Labview启动时,它会拉入应用程序的dll,将其紧紧锁定在内存中。因此,文件被锁定,Visual Studio将无法覆盖此文件(我在其他应用程序中直接看到过这种行为)。由于dll在Labview退出之前永远不会被释放,因此您需要找到一种方法来"释放"dll;技巧";每次重新编译时,Labview都会加载一个新的dll。

以下是我的建议:

在LabView中,不是像Chris Sterling建议的那样直接加载dll,而是要创建一个";包装器";dll,它将通过接口加载您的特定LabView dll

通过使用存储在包装器dll中的接口,您可以完全解耦这两个dll,这将防止包装器dll知道/锁定您的主dll。稍后,当您完成调试时,您可以直接将dll链接到LabView。

以下是代码的大致外观:

public class LabViewWrapper : IYourCustomClass
{
    private IYourCustomClass _labViewClass;
    private string labviewPath = "Full Path to labview dll";
    public LabViewWrapper()
    {
        Assembly assembly;
        try
        {
            using (FileStream fs = File.OpenRead(labviewPath))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] buffer = new byte[1024];
                    int read = 0;
                    while ((read = fs.Read(buffer, 0, 1024)) > 0)
                        ms.Write(buffer, 0, read);
                    assembly = Assembly.Load(ms.ToArray());
                    ms.Close();
                }
                fs.Close();
            }

            Type t = assembly.GetType(IYourCustomClass);
            _labViewClass= (IYourCustomClass)Activator.CreateInstance(t);
        }
        catch
        {
            // Unable to load dll dynamically
        }
    }

    // Implement all the methods in your interface with something like the following:
    /// <summary>
    /// Your Custom Method
    /// </summary>
    public void CustomLabViewMethod()
    {
        _labViewClass.CustomLabViewMethod();
    }
}

通过这种方式,您正在从内存加载dll,因此labview永远不会锁定您编译的原始dll。唯一真正的缺点是它确实使调试变得更加困难,如果你想插入断点,你可能需要直接引用源dll。

注:有一件事我不确定,但我相信会"计算";Labview是否足够聪明,可以在每次执行代码时重新构造对象,或者它是否只是在整个会话中保持相同的对象。如果它最终完成了稍后的操作,则需要向"添加代码;重新加载";每次启动自定义小部件时,文件系统中的dll。

您可以创建一个轻量级DLL包装器,它本身具有显式的主DLL运行时加载和卸载。这样包装器就会保持锁定状态,但您可以快速更新频繁更改的代码DLL。

我正在LV2012中用一个C#类做一个测试,该类在Labview VI的一个单独文件夹中有一个新的自定义类。我可以在VS2010中重新编译C#代码,而无需关闭Labview,但Labview看不到DLL的更改(如果有)。为了让Labview看到我的测试用例中的变化,它需要完全关闭并重新打开。

对于Labview C++DLL,您肯定必须关闭调用的VI,因为对DLL的引用是打开的。不过,您只需要关闭到"Labview启动"窗格。

您可以通过进入项目->属性->调试->启动外部程序,让VS在C#项目中自动生成Labview.exe。当您在VS中点击F5时,DLL会编译并生成Labview。然而,VS并没有自动将DLL附加到进程,这真的非常令人讨厌。不管有没有帮助,我都不知道。

就我个人而言,我喜欢C#方法与Labview集成的方式,但觉得C++更强大。使用C++时,您也可以以与上述类似的方式生成Labview,但它会自动将DLL附加到Labview.exe进程,使调试成为只需按F5即可完成的一步过程。你仍然可以在C++中使用类等,你只需要包装C函数就可以在Labview中调用它们。考虑到C++的一步调试和强大功能,我发现在Labview中使用外部代码时,它优于C#。

这里的术语有点不清楚,因为它指的是LV"调用"程序集,我不知道这是指在编辑时访问程序集还是在运行时实际调用它。如果是第二个,这可能解释了它被锁定的原因。

我不是.NET程序员,所以我不知道实际的解决方案是什么,但我猜你实际上不需要完全关闭LV来释放锁。关闭项目可能就足够了,尽管我知道这并不一定更好,如果锁定发生在流程级别,可能也无济于事。

gethttp://www.emptyloop.com/unlocker/unlocker -h的命令行选项

在预生成中运行。在相关dll上使用unlock命令。

如果仅解锁没有帮助,请使用解锁+删除。

简单如

Unlocker mydllpath.dll /s /d

您会发现这种行为会根据dll的分布方式而变化。如果Labview通过磁盘上的静态位置(由路径输入指定)调用程序集,您会发现在Labview应用程序打开时无法重建dll。

然而,如果dll已注册,并且Labview按名称访问它,您可以随心所欲地重建和重新安装,一旦关闭并重新打开,Labview将更新其对dll的引用。

在通过COM Interop共享.Net程序集以及将其安装到GAC时,我无意中发现了这一点。

早在2017年,知识库就有关于这个主题的文章,但现在似乎不见了。

我在这里包含了关于加载程序集的官方Labview帮助指南。