Vault Application

Hello,

We are developing an M-Files application that needs to include:

  • A Vault Application Framework 22.12 server component (C# class VaultApplication : ConfigurableVaultApplicationBase<T>), and
  • A User Interface Extensibility Framework client component (ShellUI module with right-pane dashboards and custom commands).

We would like to deploy this as a single application package.

We attempted to merge the two by updating appdef.xml like this:

 

<application type="both" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

             xsi:noNamespaceSchemaLocation="http://www.m-files.com/schemas/appdef-Server-v5.xsd">

  <guid>eb1ec555-b326-46df-899b-8ece191a08bd</guid>

  <name>My Company</name>

  <version>1.0</version>

  <required-mfiles-version>22.3.0.0</required-mfiles-version>

 

  <extension-objects>

    <extension-object>

      <name>GCG.Vault.Hybrid</name>

      <assembly>GCG.Vault.Hybrid.dll</assembly>

      <class>GCG.Vault.Hybrid.VaultApplication</class>

      <installation-method>Install</installation-method>

      <uninstallation-method>Uninstall</uninstallation-method>

      <initialization-method>Initialize</initialization-method>

      <uninitialization-method>Uninitialize</uninitialization-method>

      <start-operations-method>StartOperations</start-operations-method>

    </extension-object>

  </extension-objects>

 

  <modules>

    <module environment="shellui" fast-browsing-compatible="true">

      <file>Client/main.js</file>

    </module>

  </modules>

 

  <dashboards>

    <dashboard id="eforms-dashboard">

      <content>Client/eforms.html</content>

      <allow-selection>true</allow-selection>

    </dashboard>

  </dashboards>

</application>

 

 

We tried appdef-Server-v5.xsd as well as appdef -v5.xsd

 

When we install this application:

  • If we use appdef-server-v5.xsd, the server component loads, but the dashboard never appears.
  • If we use appdef-v5.xsd with type="both", I get an error:

The structure of the application is invalid. (Unrecognized application definition schema or application structure.)

 

So, my questions are:

  1. Does M-Files 22.12 fully support hybrid applications (type="both") with both server extension objects and client dashboards?
  2. Which schema (appdef-server-v5.xsd or appdef-v5.xsd) is correct for hybrid apps?
  3. Is there an official example or template for packaging Vault Application Framework + UIX into one app?

We have installed M-Files extension for VS-2022

Parents
  • You have asked this question in multiple places.  Please do not do that as it duplicates effort.  Your question has been answered in the Developer group: (+) VAF Application - Developer Forum - Developers - M-Files Community by  who pointed you at the documentation here: https://developer.m-files.com/Frameworks/Vault-Application-Framework/Distributing-Child-Applications/.

  • Apology for multiple posts for the question, however, I have tried and it is not working the way it is advised.
    1. I have used the server app guid in client.
    2. compiled the client app and created .mfappx.
    3. using this .mfappx in server application with below code

     

    public override void Initialize(MFilesAPI.Vault vaultSrc)
    {
    try
    {
    SysUtils.ReportToEventLog($"The application path is {Directory.GetCurrentDirectory()}", System.Diagnostics.EventLogEntryType.Information);
    string appPath = "app.mfappx";

    if (File.Exists(appPath))
    {
    vaultSrc.CustomApplicationManagementOperations.InstallCustomApplication(appPath);
    }
    else
    {
    SysUtils.ReportErrorToEventLog("File: " + appPath + " does not exist");
    }
    }
    catch (Exception ex)
    {
    if (!MFUtils.IsMFilesAlreadyExistsError(ex))
    SysUtils.ReportErrorToEventLog(ex.Message);
    }

    base.Initialize(vaultSrc);
    }

    it says in event logs
    The system cannot find the file specified. (app.mfappx)
    please note that app.mfappx is also installed as an application

  • Thanks for the response  ,

    Just to reconfirm please note the steps i followed,

    • i created client app
    • i created the server app
    • now i replaced the guid of client app with the one in server app
    • i compiled  client application and installed
    • now when i compile the server app it fails. i tried explicitly installed from the created GCG.Vault.Hybrid-1.0.mfappx it failed with the error like "DlgClientApplications.cpp, 552, The structure of the application is invalid. (Server application type must not be changed.) (0x800408E2)"

    below is the appdef.xml of client app

    <?xml version="1.0"?>
    <application xmlns:xsi="">www.w3.org/.../XMLSchema-instance" xsi:noNamespaceSchemaLocation="">www.m-files.com/.../appdef-client-v5.xsd">
    <!--<guid>ab2da4f7-90bf-45e3-9ab2-7b12eed4dc67</guid>-->
    <guid>eb1ec555-b326-46df-899b-8ece191a08bd</guid>
    <name>GCG.EForms (Advance Types)</name>
    <version>1.0</version>
    <description>Advance Control</description>
    <publisher>Muhammad Irfan</publisher>
    <copyright>GCG</copyright>
    <required-mfiles-version>20.12.0.0</required-mfiles-version>
    <optional>true</optional>
    <enabled-by-default>true</enabled-by-default>
    <modules>
    <module environment="shellui" fast-browsing-compatible="true">
    <file>Client/main.js</file>
    <!--<file>Client2/main.js</file>-->
    </module>
    </modules>
    <dashboards>
    <dashboard id="eforms-dashboard">
    <content>Client/eforms.html</content>
    <allow-selection>true</allow-selection>
    </dashboard>
    <dashboard id="advance-dashboard">
    <content>Client2/index.html</content>
    <allow-selection>true</allow-selection>
    </dashboard>
    </dashboards>
    </application>

    this is the server app appdef.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <application
    type="both"
    xmlns:xsi="">www.w3.org/.../XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="">www.m-files.com/.../appdef-server-v5.xsd">
    <guid>eb1ec555-b326-46df-899b-8ece191a08bd</guid>
    <name>GCG.Vault.Hybrid</name>
    <description></description>
    <publisher></publisher>
    <version>1.0</version>
    <copyright></copyright>
    <required-mfiles-version>22.3.0.0</required-mfiles-version>
    <multi-server-compatible>false</multi-server-compatible>
    <extension-objects>
    <extension-object>
    <name>GCG.Vault.Hybrid</name>
    <assembly>GCG.Vault.Hybrid.dll</assembly>
    <class>GCG.Vault.Hybrid.VaultApplication</class>
    <installation-method>Install</installation-method>
    <uninstallation-method>Uninstall</uninstallation-method>
    <initialization-method>Initialize</initialization-method>
    <uninitialization-method>Uninitialize</uninitialization-method>
    <start-operations-method>StartOperations</start-operations-method>
    </extension-object>
    </extension-objects>

    </application>

    Please note that either of the application is installed first the subsequent one throws the above exception.

  • The client app GUID must be different from your server app GUID.

    Your client app's appdef.xml needs a <master-application-guid> tag which references the server app's GUID as content, like so: <master-application-guid>eb1ec555-b326-46df-899b-8ece191a08bd</master-application-guid>

    See https://developer.m-files.com/Frameworks/User-Interface-Extensibility-Framework/Application-Definition/ 

  • Thank you  I see the master-application-guid was the right def.xml which shows them child under the parent. So I hope now child application will be able to communicate and access values from within the parent-app. The idea behind this is that we want a value, specifically, the class value to be set in configuration of Vault and make this class readable from client application. 

    Needful in these lines will be helpful.

    Thanks you once again

  • Simply bundling the applications will not do this.  You need to create a vault extension method in the VAF application which returns the data you need, then call that from the UI application.

  • Thank you  , 

    I agree with you and i have created a comprehensive Vault application that interacts with the external Web Service, in fact for a signing solution. It works fine. Now there was a requirement to exchange the information between Vault Server(e.g. taking class name set in the configuration) and accessing it in UI application. 
    I was expecting a guide that could help me grab the class name from Server Configured and accessed in UI. 

    Appreciate your timely response always. 

  • Thank you  , your response and the example in the above link does make sense to me.

    However, being occupied to another work, I am not able to give it a try this moment. I will check it in practical a bit later. Looking into the example and how both apps are wired-up makes sense to me. I will give it a try and get back to you.  

    Thank you once again. 

  • Hi  , followed the example in provided link UIX to Server but trying multiple tries ending up with the error saying "TypeError: shellFrame.ShellUI.Vault.Async.ExtensionMethodOperations.ExecuteVaultExtensionMethod is not a function"

    the below server method is never reached


    [VaultExtensionMethod("VaultExtensionMethod_VAF", RequiredVaultAccess = MFVaultAccess.MFVaultAccessNone)]
    private string TestVaultExtensionMethod(EventHandlerEnvironment env)
    {
    SysUtils.ReportInfoToEventLog("Reached to server");
    return DateTime.Now.ToLongTimeString()
    + " (the input received from client was: " + env.Input
    + ")";
    }

    client method i called as per website example

    shellFrame.ShellUI.Vault.Async.ExtensionMethodOperations.ExecuteVaultExtensionMethod(
    "VaultExtensionMethod_VAF", // The name of the extension method to execute.
    "world", // The input (string) to pass it.
    function (response) {
    // The output (string) will be in response; show it.
    MFiles["ShowToast"](response);
    });

    even i tried 

    shellFrame.ShellUI.Vault.ExtensionMethodOperations.ExecuteVaultExtensionMethod(
    "VaultExtensionMethod_VAF", // The name of the extension method to execute.
    "world")}

  • Hi  , The difference i see is that example is xsi:noNamespaceSchemaLocation="www.m-files.com/.../appdef-server-v1.xsd" whereas we are using 

    xsi:noNamespaceSchemaLocation="www.m-files.com/.../appdef-server-v5.xsd"

    Both the applications are explicitly installed, the server and client ones and they are well classified as child under the parent. 

    My Server method is as below

    [VaultExtensionMethod("VaultExtensionMethod_VAF", RequiredVaultAccess = MFVaultAccess.MFVaultAccessNone)]
    private string VaultExtensionMethod(EventHandlerEnvironment env)
    {
    SysUtils.ReportInfoToEventLog("Reached to server");
    return DateTime.Now.ToLongTimeString()
    + " (the input received from client was: " + env.Input
    + ")";
    }

    My client call is as under

    else if (commandId === serverCall) {
    console.log("will call the server method now");
    shellFrame.ShellUI.Vault.Async.ExtensionMethodOperations.ExecuteVaultExtensionMethod(
    "VaultExtensionMethod_VAF", // The name of the extension method to execute.
    "world", // The input (string) to pass it.
    function (response) {
    // The output (string) will be in response; show it.
    MFiles["ShowToast"](response);
    });
    }

     It writes correctly the console log but fails when making call and throws

    shellFrame.ShellUI.Vault.Async.ExtensionMethodOperations.ExecuteVaultExtensionMethod is not a function

    Difference is only that I am not running/overriding the 

    protected override void InitializeApplication(Vault vault)

    why i am skipping that is that my application is already installed correctly classified (parent-client) as i explained earlier. 

    Would appreciate the earlier response. 

  • The schema won't matter; keep it as the later one.  Are you using UIXv2 or UIXv1?  This is an older sample for UIXv1 so the specific code shown won't work in UIXv2, but the concept of declaring and calling the vault extension method is identical.  If you do a search on this site you'll be able to find a UIXv2 version.

Reply Children