Check connection with Vault

Check connection with Vault

gert-leonvanlier
Collaborator Collaborator
3,710 Views
22 Replies
Message 1 of 23

Check connection with Vault

gert-leonvanlier
Collaborator
Collaborator

I have looked through a large number of forum post about this subject, but nothing that answers my problem.

I have the following code (copied) from this post:

 

 

using Connectivity.InventorAddin.EdmAddin;
using VDF = Autodesk.DataManagement.Client.Framework.Vault;
using System.Windows.Forms;

public void SetupUserInterace(Inventor.ApplicationAddInSite applicationAddInSite, bool firstTime, string clientID)
{
	if (firstTime)
	{
		EdmSecurity edmSecurity = EdmSecurity.Instance;
		var vaultServerName = edmSecurity.GetEdmLoginPreferences().Server;
		var vaultName = edmSecurity.GetEdmLoginPreferences().VaultName;
		var vaultUserName = edmSecurity.GetEdmLoginPreferences().UserName;
		var vaultPassword = edmSecurity.GetEdmLoginPreferences().Password;

		VDF.Results.LogInResult logInResults;
		logInResults = VDF.Library.ConnectionManager.LogIn(vaultServerName, vaultName, vaultUserName, vaultPassword, VDF.Currency.Connections.AuthenticationFlags.Standard, null);

		VDF.Currency.Connections.Connection connection = null;

		if (logInResults.Success)
		{
			connection = logInResults.Connection;
			MessageBox.Show("There is a connection with the Houten Vault.");
		}

	}
}

 

 

 

The trouble I am having is how to get necessary inputs for this method. I wanna call this method at a specific moment in my add in. The add in itself gets the ApplicationAddInSite object, but I can't figure out how to pass it in my method. firstTime I am not sure if necessary? I think I always want to check if the connection still exists.

clientID: is that the Guid of my add in or of the Vault add in for Inventor? If it is the latter, how do I find this value?

 

To add: what I want, is to pass a value to the comment field when checking in a file to the Vault when the user clicks check in.

0 Likes
Accepted solutions (1)
3,711 Views
22 Replies
Replies (22)
Message 2 of 23

yan.gauthier
Advocate
Advocate

This method was custom made by someone. If you don't use the ClientID, remove it. If you have setup that you automatically connect to the vault on Inventor Startup, you could simply use this code instead:

 

//Use Inventor Vault Addin connection
EdmSecurity edmSecurity = EdmSecurity.Instance;

if (!edmSecurity.IsSignedIn())
{
      edmSecurity.OnLoginButtonExecute(true); //simulate login button being pressed
}

 

0 Likes
Message 3 of 23

gert-leonvanlier
Collaborator
Collaborator

That's great. Thank you.

 

Do you know if there is way to access the comment field at check in with one or the other API?

0 Likes
Message 4 of 23

yan.gauthier
Advocate
Advocate

Hi, 

 

Something like this should work:

 

string vaultpath = DocumentPath;

string root = System.IO.Path.GetDirectoryName(edmSecurity.InventorApp.DesignProjectManager.ActiveDesignProject.FullFileName);
       
 //replace PC Workspace path to become Vault Root
vaultpath = vaultpath.Replace(root, "$");

//vault uses forward slash (/) as separator instead of Windows backslash (\)
vaultpath = vaultpath.Replace(System.IO.Path.DirectorySeparatorChar, '/');

//Path must be in an array
string[] filepath = new string[] { vaultpath };

//Find latest version of the file in the vault
Autodesk.Connectivity.WebServices.File[] file = connection.WebServiceManager.DocumentService.FindLatestFilesByPaths(filepath);
                
if (file[0].Id == -1)
{
     //File Was not found
     return false;
}

//Create a fileIteration

VDF.Vault.Currency.Entities.FileIteration fileIteration = new VDF.Vault.Currency.Entities.FileIteration(connection, file[0]);

var comment = connection.PropertyManager.GetPropertyValue(fileIteration, connection.PropertyManager.GetPropertyDefinitionBySystemName(PropertyDefinitionIds.Server.Comment), null);
Message 5 of 23

gert-leonvanlier
Collaborator
Collaborator

That looks very promising. I will test with this after the weekend.

0 Likes
Message 6 of 23

gert-leonvanlier
Collaborator
Collaborator

I tried our code, but somehow I don't get a connection with the Vault. loginResults.Connection is not getting true. vaultServerName, vaultName, vaultUserName and vaultPassword are correct during runtime.

string progId = "Inventor.Application";
Type inventorApplicationType = Type.GetTypeFromProgID(progId);

Inventor.Application invApp = (Inventor.Application)Marshal.GetActiveObject(progId);

//Get the active document in Inventor
Document document = (Document)invApp.ActiveDocument;
var vaultPath = document.FullFileName.ToString();

EdmSecurity edmSecurity = EdmSecurity.Instance;

var vaultServerName = edmSecurity.GetEdmLoginPreferences().Server;
var vaultName = edmSecurity.GetEdmLoginPreferences().VaultName;
var vaultUserName = edmSecurity.GetEdmLoginPreferences().UserName;
var vaultPassword = edmSecurity.GetEdmLoginPreferences().Password;

VDF.Vault.Results.LogInResult logInResults;
logInResults = VDF.Vault.Library.ConnectionManager.LogIn(vaultServerName, vaultName, vaultUserName, vaultPassword, VDF.Vault.Currency.Connections.AuthenticationFlags.Standard, null);

VDF.Vault.Currency.Connections.Connection connection = null;

if (logInResults.Success)
{
	connection = logInResults.Connection;
	MessageBox.Show("There is a connection with the Vault.");
}

var root = System.IO.Path.GetDirectoryName(edmSecurity.InventorApp.DesignProjectManager.ActiveDesignProject.FullFileName);

//replace PC Workspace path to become Vault Root
vaultPath = vaultPath.Replace(root, "$");

//vault uses forward slash (/) as separator instead of Windows backslash (\)
vaultPath = vaultPath.Replace(System.IO.Path.DirectorySeparatorChar, '/');

//path must be in an array
string[] filePath = new string[] { vaultPath };

if (!edmSecurity.IsSignedIn())
{
	edmSecurity.OnLoginButtonExecute(true);
}


//find latests version of the file in Vault
Autodesk.Connectivity.WebServices.File[] file = connection.WebServiceManager.DocumentService.FindLatestFilesByPaths(filePath);

if (file[0].Id == -1)
{
	//file was not found
	//return false;
}

//create a file iteration
VDF.Vault.Currency.Entities.FileIteration fileIteration = new VDF.Vault.Currency.Entities.FileIteration(connection, file[0]);

var comment = connection.PropertyManager.GetPropertyValue(fileIteration, connection.PropertyManager.GetPropertyDefinitionBySystemName(VDF.Vault.Currency.Properties.PropertyDefinitionIds.Server.Comment), null);

 

 

Am I doing something wrong here?

 

0 Likes
Message 7 of 23

yan.gauthier
Advocate
Advocate

Hi,

 

Since you are using EdmSecurity (Inventor Vault Addin), you might already be logged in. Maybe your login does not return success since you are already connected.

 

use the test I proposed in my earlier post to see.

0 Likes
Message 8 of 23

gert-leonvanlier
Collaborator
Collaborator

This works! I can now read the comment field from the Vault.

Next step is to set the value of the comment field at check in. So when the user clicks on check in, a value is set at the comment field box in the check in window. See the image.

Is this possible?

 

iu6Ivqq4kM.png

0 Likes
Message 9 of 23

yan.gauthier
Advocate
Advocate

from the Vault SDK:

 

FileIteration CheckinFile( 
   FileIteration file,
   System.string comment,
   System.bool keepCheckedOut,
   FileAssocParam[] associations,
   BOM bom,
   System.bool copyBom,
   System.string newFileName,
   FileClassification classification,
   System.bool hidden,
   FilePathAbsolute filePath
)

Parameters
 
file: The file to check-in.
 
comment: Text data to be associated with the check-in.
 
keepCheckedOut: If true, the new version gets uploaded and versioned, but the file is still checked out to the user.
 
associations: The associations on the file.
 
bom: A bill of materials to associate with this file. Null should be passed in if there is no BOM.
 
copyBom: If this value is true and the 'bom' parameter is null, the BOM from the previous version will be copied for this version.
 
newFileName: Allows the file to be renamed during check-in. Pass in null to keep the file name the same.
 
classification: The classification for the file.
 
hidden: A flag to indicate if a file should be hidden.
 
filePath: The location of the file on disk. If null, the working folder location will be used.
 
Return Value: The newly created iteration of the file
 

 

Accessed from connection.FileManager.CheckinFile

0 Likes
Message 10 of 23

gert-leonvanlier
Collaborator
Collaborator

Is there any documentation on this? I can't find anything about the Vault API.

0 Likes
Message 11 of 23

gert-leonvanlier
Collaborator
Collaborator
This looks great. But isn't this a "stand alone" function? I want to fill in the comment field when the user clicks the check in button on the ribbon or using the Vault tab.
0 Likes
Message 12 of 23

yan.gauthier
Advocate
Advocate
Accepted solution

To get the documentation, you need to install the Vault SDK which should be in your Vault install folder (e.g.: C:\Program Files\Autodesk\Vault Basic 2020\SDK)

 

But no, you won't be able to set an event to inject a comment before the check-in dialog opens. Check-in is a Vault Addin function, not an Inventor function. you would need to create your own form to replace the check-in form.

You should close this thread and open a new one to ask if it is possible to change the comment of a vault file after check-in ?

Message 13 of 23

gert-leonvanlier
Collaborator
Collaborator
Thank you.

A shame to hear that, but I was preparing for this answer. I guess we have to find another solution then.
0 Likes
Message 14 of 23

matt_jlt
Collaborator
Collaborator

There is a pretty complicated method in achieveing this and it took me hours and hours get get all the window ID's etc. The two methods i have listed below work well about 99% of the time,  but i have had some issues when they were used in combination with batch processing via API, and if that is your overall intention then i suggest using the Vault API to manage this, although i have never used Vault to check in files as i don't want to end up breaking file associations etc and mess it all up.

 

Method 1 - Send Keys (Less reliable than method 2)

    Sub InventorAddin_VaultCheckIn(ByVal strComment As String)
        ' Initialise checkout, use execute 2(False) to wait for keys / entry before proceeding)
        ThisApplication.CommandManager.ControlDefinitions.Item("VaultCheckinTop").Execute2(False)

        ' Using sendwait as it waits for each key to be preocessed before continuing
        System.Windows.Forms.SendKeys.SendWait(strComment & ControlChars.Tab & ControlChars.CrLf)

    End Sub

 

Method 2 - This is the main part 90% worked out for you. When running manually (again, a user clicking the check-in button, and not running inventro via the API in a batch process) this worked 100% of the time.

The example below is getting the Check In form using the WIN32 API and automatically clicking the "OK" button. I didn't edit the comments field in this one but it's reasonably straight forward to work that out once you have the dialog / form. 

The code gets  inserted into the "StandardAddInServer.vb" module, just don't forget you need to declare all the win32 functions etc.

 

FYI, it took me a crazy amount of time to work out how to get this dialog. Would be great if Autodesk would expose it in the API.

        Private Sub OnWindowOpened(sender As Object, oAutomationEventArgs As AutomationEventArgs)
            ' Check if is currently enabled
            'If My.Settings.bAutoCloseCheckInForm = False Then Return

            Try
                Dim element As AutomationElement = sender
                If element Is Nothing Then Return
                ThisApplication.StatusBarText = element.Current.Name
                If element.Current.Name.Count < 11 Then Return ' Needs to have enough characters to check length
                If Left(element.Current.Name, 10) <> "Check In '" Then Return
                ' wait for form to load (closing too early causes problems / skipping)
                sharedFunctions.IsInventorAvailable(ThisApplication, 2)
                Dim h1 = element.Current.NativeWindowHandle
                ThisApplication.StatusBarText = h1
                'Dim H2 = FindWindowEx(h1, IntPtr.Zero, "OK", "")
                Dim h2 = GetDlgItem(h1, "00000001") ' OK button is ID "00000001", Cancel button is "00000002"

                If h2 <> 0 Then
                    'SendMessage(h2, WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero) 'trying wihtout set focus
                    SendMessage(h2, BM_CLICK, IntPtr.Zero, IntPtr.Zero)
                    'SendMessage(H2, BM_SETCHECK, False, 0)
                    ' this removes the event handler if it was a once only operation
                    'System.Windows.Automation.Automation.RemoveAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, AddressOf OnWindowOpened)
                Else
                    MessageBox.Show("Didnt get it")
                End If
            Catch
            End Try
        End Sub

  

Message 15 of 23

matt_jlt
Collaborator
Collaborator

I realized there was an external function called, but its self explanatory with the comment above it. Just do something like wait or a timer that won't lock up the process, should be fine.

0 Likes
Message 16 of 23

gert-leonvanlier
Collaborator
Collaborator

Wow! I think you actually created here what my next step for a solution would be as described here.

 

So I would have to use the Win32 API to find the window and then call your method? Do you maybe have any examples on this?

0 Likes
Message 17 of 23

matt_jlt
Collaborator
Collaborator

That is a working example for the code (just doesn't have all of the win32 API functions declared).

What it does is monitors inventor for the open window event, then when triggered, it checks it's name, then if it matches, it used the win32 api to interface with it. 

 

I would help you find the id for the text box but i can't at the moment due to vault maintenance. But you can use spy++ (from within visual studio) to find that.

 

I assumed you were talking about method 2. If not, the first method is already working as is.

0 Likes
Message 18 of 23

gert-leonvanlier
Collaborator
Collaborator

If I understand correctly, I need the Win32 API to watch for if the window gets opened or how is the sub in method 2 triggered?

0 Likes
Message 19 of 23

matt_jlt
Collaborator
Collaborator

Sorry, i forgot to tell you how it is initialised

 

 

Imports System.Windows.Automation ' this is for the check in window handler

 

This needs to be added into the Activate sub

 

' ** GET WINDOW CODE
System.Windows.Automation.Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, AddressOf OnWindowOpened)

 

 

 

Message 20 of 23

matt_jlt
Collaborator
Collaborator

Thought i would also give you a simple function for your original question aswell

 

Imports oEDM = Connectivity.InventorAddin.EdmAddin

 

 

 

    Function Vault_CheckInventorVaultIsActive() As Boolean
        ' Check that the inventor addin vault connection is active
        Try
            If oEDM.EdmSecurity.Instance.IsSignedIn Then
                Return True
            Else
                MessageBox.Show("Inventor Vault Not Logged In")
                Return False
            End If
        Catch ex As Exception
            ' Do nothing
        End Try
        Return False ' Sign in not found
    End Function