Select to view content in your preferred language

Get Addin info Pro 3.0

2435
17
Jump to solution
07-12-2022 10:47 AM
AbelPerez
Occasional Contributor III

At Pro 2.9 there was this great helper class that got info for your own addin. https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Content/AddInInfoManager

It bombs at 3.0 and I have not been able to locate an alternative API or other form of getting the info programmatically.

I tweaked the function and it turns out the the code is returning zero guid attributes:

        public static string GetAddInGuid()
        {
            // get the GUID that identifies the current add-in
            Assembly exAssembly = Assembly.GetExecutingAssembly();
            //GuidAttribute gAttribute = (GuidAttribute)exAssembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
            object[] custAtts = exAssembly.GetCustomAttributes(typeof(GuidAttribute), true);
            if (custAtts.Length == 0)
            {
                throw new Exception("No custom attributes.");
            }
            GuidAttribute gAttribute = (GuidAttribute)custAtts[0];

            // guid={903288ab-2c9c-4e49-8a3d-0321f68425c1}
            return string.Format("{{{0}}}", gAttribute.Value);
        }

 

Anyone know an alternative to programmatically get info for your own addin or just the GUID?

0 Kudos
17 Replies
AbelPerez
Occasional Contributor III

Unfortunately my knowledge base is limited when it comes to the writing of the assembly. But my tests showed that something is missing.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I am still looking at this issue.   I was able to duplicate the difference in behavior between an Addin that is migrated to 3.0 and an Addin that is built with 3.0.   

When migrating to 3.0 the migration process retains the existing AssemblyInfo.cs file (where the Assembly Guid attribute is set) and then sets the tag "GenerateAssemblyInfo" in the project file to false (false means the AssemblyInfo is used instead of auto generated assembly info).   After migrating a project to 3.0 the Assembly Guid attribute is extracted from the migrated AssemblyInfo.cs (in essence this works just like in 2.x).   This doesn't happen when creating a new project using the Addin project template because it is using the .Net default (which is: GenerateAssemblyInfo = true) which doesn't create the assembly info source and apparently doesn't generate an Assembly Guid attribute.  I am trying to find another way to get the Guid.   

As a workaround you could change the project file and add this under the first PropertyGroup tag:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

and then add a n AssemblyInfo.cs file under the project's Properties folder (use and modify an AssemblyInfo.cs file from community samples).

0 Kudos
AbelPerez
Occasional Contributor III

@Wolf  thank you so much. I also sent you some suggestions on the class methods.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I tried this method on both 2.x migrated projects and 3.0 created addin projects.  There might be a better way to do this but for the time being this should work:

    public static string GetAddInGuid()
    {
      // get the GUID that identifies the current add-in
      Assembly exAssembly = Assembly.GetExecutingAssembly();
      var dirs = exAssembly.Location.Split(System.IO.Path.DirectorySeparatorChar);
      if (dirs.Length > 2
          && Guid.TryParse(dirs[dirs.Length - 2], out Guid assemblyGuid))
      {
        return assemblyGuid.ToString();
      }
      throw new Exception($@"Assembly path doesn't contain a GUID: {exAssembly.Location}");
    }
0 Kudos
AbelPerez
Occasional Contributor III

Ok let me try this. thank you.

AbelPerez
Occasional Contributor III

Ok your alternative code works! Thank you so much. I made some very small modifications so that we can keep the prior logic, and it that doesn't work then use the new logic. I also wrapped the GUID with squigglies as that is probably what users expect. I also didn't want an exception thrown so on a fail I just return an empty string.

Here is my mod to your code:

 

        /// <summary>
        /// Get the current add-in module's daml / AddInInfo Id tag (which is the same as the Assembly GUID)
        /// </summary>
/// <returns></returns>
public static string GetAddInId()
{
    // Module.Id is internal, but we can still get the GUID from the assembly
    var assembly = Assembly.GetExecutingAssembly();
    //var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
    object[] custAtts = assembly.GetCustomAttributes(typeof(GuidAttribute), true);
    Debug.Print("custAtts.Count={0}", custAtts.Count());
    if (custAtts.Count() > 0)
    {
        GuidAttribute attribute = (GuidAttribute)custAtts[0];

        string aguid = string.Format("{{{0}}}", attribute.Value);
        return aguid;
    }
    else
    {
        // if no custom attributes returned then try through the assembly location which has the GUID
        // embedded in the path. 
        Debug.Print("assembly.Location={0}", assembly.Location);
        var dirs = assembly.Location.Split(Path.DirectorySeparatorChar);
        if (dirs.Length > 2 && Guid.TryParse(dirs[dirs.Length - 2], out Guid assemblyGuid))
        {
            Debug.Print("assemblyGuid={0}", assemblyGuid.ToString());
            string aguid = string.Format("{{{0}}}", assemblyGuid.ToString());
            return aguid;
        }
        else
        {
            //throw new Exception($@"Assembly path doesn't contain a GUID: {assembly.Location}");
            Debug.Print($@"Assembly path doesn't contain a GUID: {assembly.Location}");
            return string.Empty;
        }
    }
}

 

 I 

Wolf
by Esri Regular Contributor
Esri Regular Contributor

Thanks for your diligence on this issue.  Also @UmaHarano wanted me to let you know that the API now has the AddInInfo Class

You can retrieve the list of all AddInInfos using FrameworkApplication.GetAddInInfos()

Using your GetAddInId() helper method allows to select the AddInInfo object for the running AddIn - here is the sample code for getting an AddInInfo instance for the running AddIn:

protected override void OnClick()
{
  try
  {
    // get the ID of this Addin
    var myAddinGuid = GetAddInGuid();
    var addinInfos = FrameworkApplication.GetAddInInfos();
    var myAddin = addinInfos.Where(x => x.ID == myAddinGuid).FirstOrDefault();
    if (myAddin != null)
    {
      MessageBox.Show(GetAddInInfoDetail(myAddin));
    }
    else
      throw new Exception("Can't find Addin Guid");
  }
  catch (Exception ex)
  {
    MessageBox.Show($@"Error: {ex.ToString()}");
  }
}

private static string GetAddInInfoDetail(AddInInfo info)
{
  StringBuilder sb = new();
  sb.AppendLine($"Addin: {info.Name}");
  sb.AppendLine($"Description {info.Description}");
  sb.AppendLine($"ImagePath {info.ImagePath}");
  sb.AppendLine($"Author {info.Author}");
  sb.AppendLine($"Company {info.Company}");
  sb.AppendLine($"Date {info.Date}");
  sb.AppendLine($"Version {info.Version}");
  sb.AppendLine($"FullPath {info.FullPath}");
  sb.AppendLine($"DigitalSignature {info.DigitalSignature}");
  sb.AppendLine($"IsCompatible {info.IsCompatible}");
  sb.AppendLine($"IsDeleted {info.IsDeleted}");
  sb.AppendLine($"TargetVersion {info.TargetVersion}");
  sb.AppendLine($"ErrorMsg {info.ErrorMsg}");
  sb.AppendLine($"ID {info.ID}");
  sb.AppendLine("");
  return sb.ToString();
}

private static string GetAddInGuid()
{
  // get the GUID that identifies the current add-in
  Assembly exAssembly = Assembly.GetExecutingAssembly();
  var dirs = exAssembly.Location.Split(System.IO.Path.DirectorySeparatorChar);
  if (dirs.Length > 2
      && Guid.TryParse(dirs[dirs.Length - 2], out Guid assemblyGuid))
  {
    return $@"{{{assemblyGuid.ToString()}}}";
  }
  throw new Exception($@"Assembly path doesn't contain a GUID: {exAssembly.Location}");
}

 

0 Kudos
AbelPerez
Occasional Contributor III

Yes thank you, I have that in my code from the 2.x days.

0 Kudos