This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Help request for GitHub sample UsingManagedAssemblies

Hello everyone,

I would like to create an UI extension add-on for M-Files, but I am new to developing for M-Files,
so I decided to start with adjusting the sample code and see where it gets me.

1. I downloaded UsingManagedAssemblies sample from github:
https://github.com/M-Files/MFilesSamplesAndLibraries/tree/master/Samples/UIX%20Applications/UsingManagedAssemblies
2. I zipped the contents of uix folder and installed it to [color=blue]MyVault[/color] using the M-Files Admin tool.
3. Upon entering [color=blue]MyVault[/color] using the M-Files Online explorer, I got a popup window stating: "MyVault says Hello!".
4. I was happy to have successfully installed and ran the sample add-on!

Next, I wanted to add an extra method to the:

Class1.cs file:

public class Class1 {
public void ShowMessage(Int32 parentHWND, string message, dynamic vault) {
// Get a reference to the window from the provided handle.
IWin32Window parentWindow = Control.FromHandle((IntPtr)parentHWND);

// Show the message.
MessageBox.Show(parentWindow, $"{vault.Name} says {message}");
}

public string GetString() {
return "GetString()";
}
}


main.js file:

function getShellFrameStartedHandler(shellFrame) {
return function() {
var clrObject = MFiles.CreateObjectCLR( "MyClassLibrary.dll", "MyClassLibrary.Class1" );
        var myString = clrObject.GetString();
clrObject.ShowMessage( shellFrame.OuterWindow.Handle, "Hello!", shellFrame.ShellUI.Vault );
};
}


So that I can use myString value instead of the hardcoded: "Hello!" string in the line:
[size=12pt]clrObject.ShowMessage( shellFrame.OuterWindow.Handle, "Hello!", shellFrame.ShellUI.Vault );[/size]
(I did not change the "Hello!" string for myString variable yet. I only added the var myString = clrObject.GetString(); into the main.js file)

I zipped the new .dll and main.js together with appdef.xml into a .zip file and installed it onto [color=blue]MyVault[/color] again.

Upon opening [color=blue]MyVault[/color] using the M-Files Online explorer I get the following error message:
https://imgur.com/a/2iIT4zg
(The green text is my translation for you)
With the following details:
CoScriptDelegate_Events.cpp, 396, Objekt nepodporuje t?to vlastnosť alebo met?du (0x80040008)
IDispatchInvocation.cpp, 96, Objekt nepodporuje t?to vlastnosť alebo met?du (0x80040008)
Managed Assemblies: main.js, 49, Objekt nepodporuje t?to vlastnosť alebo met?du (0x80040008)
MErrorHelper.cpp, 2457, Objekt nepodporuje t?to vlastnosť alebo met?du (0x80040008)
(M-Files 20.1.8669.3)


Does anyone know what is the problem?
What am I doing wrong?


The uix.zip can be found in the attachments.
uix.zip
Parents
  • Hi Marian,

    I have just tested here (code below, for your reference) and got a message saying "Hello!Craig" (yes, I forgot a space). My current assumption is that the DLL was locked on your machine when you updated the application (Windows Explorer tends to do this with managed assemblies; it's one of the most awkward things about using them) and is giving you the previous version of the DLL (the one without the GetString method).

    Can you try completely killing the Windows Explorer and the M-Files Desktop Client processes (or rebooting) and trying to access it again?

    Altered Class1.cs:

    using System;
    using System.Windows.Forms;

    namespace MyClassLibrary
    {
    ///
    /// The class which will be instantiated from the UIX application.
    ///
    public class Class1
    {
    public string GetString()
    {
    return "Craig";
    }

    ///
    /// Shows a message from within the managed assembly.
    ///
    /// A handle for the parent window (see www.m-files.com/.../index.html
    /// The message to show, which will be prefixed by the vault name.
    /// The M-Files API Vault object (see www.m-files.com/.../index.html
    public void ShowMessage(Int32 parentHWND, string message, dynamic vault)
    {
    // Get a reference to the window from the provided handle.
    IWin32Window parentWindow = Control.FromHandle((IntPtr)parentHWND);

    // Show the message.
    MessageBox.Show(parentWindow, $"{vault.Name} says {message}");
    }
    }
    }


    Altered main.js:

    // NOTE! This code is for demonstration purposes only and does not contain any kind of
    // error handling. MUST be revised before using in production.

    "use strict";

    function OnNewShellUI( shellUI )
    {
    // This is the start point of a ShellUI module.

    // Register to be notified when a new normal shell frame (Event_NewNormalShellFrame) is created.
    // We use Event_NewNormalShellFrame rather than Event_NewShellFrame as this won't fire for history (etc.) dialogs.
    // ref: www.m-files.com/.../index.html
    shellUI.Events.Register(
    Event_NewNormalShellFrame,
    handleNewNormalShellFrame );
    }

    function handleNewNormalShellFrame(shellFrame)
    {
    /// Handles the OnNewNormalShellFrame event for an IShellUI.
    /// The shell frame object which was created.

    // The shell frame was created but it cannot be used yet.
    // The following line would throw an exception ("The object cannot be accessed, because it is not ready."):
    // shellFrame.ShowMessage("A shell frame was created");

    // Register to be notified when the shell frame is started.
    // This time pass a reference to the function to call when the event is fired.
    shellFrame.Events.Register(
    Event_Started,
    getShellFrameStartedHandler(shellFrame) );
    }

    function getShellFrameStartedHandler(shellFrame)
    {
    /// Returns a function that handles the OnStarted event for an IShellFrame.

    return function()
    {
    // The shell frame is now started and can be used.

    // Instantiate the managed object.
    // ref: www.m-files.com/.../index.html
    // In the case below "MyClassLibrary.dll" is the name of the file to load the class from.
    // In this case, the file is loaded from the root of the UIX application.
    // "MyClassLibrary.Class1" is the full class name (including namespace) to instantiate.
    // This class must have an accessible constructor.
    var clrObject = MFiles.CreateObjectCLR( "MyClassLibrary.dll", "MyClassLibrary.Class1" );

    // Call the "ShowMessage" method on the CLR object.
    clrObject.ShowMessage( shellFrame.OuterWindow.Handle, "Hello!" + clrObject.GetString(), shellFrame.ShellUI.Vault );
    };
    }



    Regards,

    Craig.
Reply
  • Hi Marian,

    I have just tested here (code below, for your reference) and got a message saying "Hello!Craig" (yes, I forgot a space). My current assumption is that the DLL was locked on your machine when you updated the application (Windows Explorer tends to do this with managed assemblies; it's one of the most awkward things about using them) and is giving you the previous version of the DLL (the one without the GetString method).

    Can you try completely killing the Windows Explorer and the M-Files Desktop Client processes (or rebooting) and trying to access it again?

    Altered Class1.cs:

    using System;
    using System.Windows.Forms;

    namespace MyClassLibrary
    {
    ///
    /// The class which will be instantiated from the UIX application.
    ///
    public class Class1
    {
    public string GetString()
    {
    return "Craig";
    }

    ///
    /// Shows a message from within the managed assembly.
    ///
    /// A handle for the parent window (see www.m-files.com/.../index.html
    /// The message to show, which will be prefixed by the vault name.
    /// The M-Files API Vault object (see www.m-files.com/.../index.html
    public void ShowMessage(Int32 parentHWND, string message, dynamic vault)
    {
    // Get a reference to the window from the provided handle.
    IWin32Window parentWindow = Control.FromHandle((IntPtr)parentHWND);

    // Show the message.
    MessageBox.Show(parentWindow, $"{vault.Name} says {message}");
    }
    }
    }


    Altered main.js:

    // NOTE! This code is for demonstration purposes only and does not contain any kind of
    // error handling. MUST be revised before using in production.

    "use strict";

    function OnNewShellUI( shellUI )
    {
    // This is the start point of a ShellUI module.

    // Register to be notified when a new normal shell frame (Event_NewNormalShellFrame) is created.
    // We use Event_NewNormalShellFrame rather than Event_NewShellFrame as this won't fire for history (etc.) dialogs.
    // ref: www.m-files.com/.../index.html
    shellUI.Events.Register(
    Event_NewNormalShellFrame,
    handleNewNormalShellFrame );
    }

    function handleNewNormalShellFrame(shellFrame)
    {
    /// Handles the OnNewNormalShellFrame event for an IShellUI.
    /// The shell frame object which was created.

    // The shell frame was created but it cannot be used yet.
    // The following line would throw an exception ("The object cannot be accessed, because it is not ready."):
    // shellFrame.ShowMessage("A shell frame was created");

    // Register to be notified when the shell frame is started.
    // This time pass a reference to the function to call when the event is fired.
    shellFrame.Events.Register(
    Event_Started,
    getShellFrameStartedHandler(shellFrame) );
    }

    function getShellFrameStartedHandler(shellFrame)
    {
    /// Returns a function that handles the OnStarted event for an IShellFrame.

    return function()
    {
    // The shell frame is now started and can be used.

    // Instantiate the managed object.
    // ref: www.m-files.com/.../index.html
    // In the case below "MyClassLibrary.dll" is the name of the file to load the class from.
    // In this case, the file is loaded from the root of the UIX application.
    // "MyClassLibrary.Class1" is the full class name (including namespace) to instantiate.
    // This class must have an accessible constructor.
    var clrObject = MFiles.CreateObjectCLR( "MyClassLibrary.dll", "MyClassLibrary.Class1" );

    // Call the "ShowMessage" method on the CLR object.
    clrObject.ShowMessage( shellFrame.OuterWindow.Handle, "Hello!" + clrObject.GetString(), shellFrame.ShellUI.Vault );
    };
    }



    Regards,

    Craig.
Children
No Data