I am reaching out to discuss an issue we've encountered while testing the distribution version of our Excel add-in.
Upon running the packaged XLL file, we encountered the following error message:
"An exception occurred while calling function GetDynamicStatus. The exception message is: Parameter is not valid."
This error seems to be related to the GetDynamicStatus function within the add-in. It appears to be encountering an invalid parameter during its execution.
We're currently investigating this discrepancy, as the error doesn't occur when running the project directly but arises specifically when using the packaged file intended for distribution.
Below is code for reference :-
using ExcelDna.Integration.CustomUI;
using ExcelDna.Integration;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Timers;
namespace BanorCapital
{
[ComVisible(true)]
public partial class RibbonController : ExcelRibbon, IDisposable
{
private Microsoft.Office.Core.IRibbonUI _ribbonUi;
private static RibbonController instance;
private string selectedDataSource = "Influx";
private bool isFlagEnabled = false;
private System.Timers.Timer timer;
string timezone =
TimeZoneInfo.Local.Id;
public static RibbonController Instance
{
get { return instance; }
}
public RibbonController()
{
// Initialize timer with 10 seconds interval
timer = new System.Timers.Timer(10000);
timer.Elapsed += Timer_Elapsed;
timer.Start();
// Get the timezone identifier in "Continent/City" format
timezone = GetTimeZoneId();
}
private string GetTimeZoneId()
{
TimeZoneInfo localTimeZone = TimeZoneInfo.Local;
return localTimeZone.DisplayName;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// Call GetButtonImage to update the button image
_ribbonUi.InvalidateControl("status_button");
}
public string SelectedDataSource
{
get { return selectedDataSource; }
set { selectedDataSource = value; }
}
/// <summary>
/// Gets the Excel application instance.
/// </summary>
private Microsoft.Office.Interop.Excel.Application App
{
get => (Microsoft.Office.Interop.Excel.Application)ExcelDnaUtil.Application;
}
/// <summary>
/// Handles the Ribbon load event.
/// Initializes the IRibbonUI interface.
/// </summary>
public void OnLoad(Microsoft.Office.Core.IRibbonUI ribbonUI)
{
_ribbonUi = ribbonUI;
instance = this; // Assign the current instance to the static property
}
/// <summary>
/// Handles the "Settings" button click on the Ribbon.
/// Displays the login form if the user is not already authenticated.
/// </summary>
public void OnSettings(Microsoft.Office.Core.IRibbonControl control)
{
if (IsUserAuthenticated())
{
MessageBox.Show("You are already logged in.", "Already Logged In", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (!IsUserAuthenticated())
{
var loginForm = new LoginForm();
DialogResult result = loginForm.ShowDialog();
if (result != DialogResult.OK)
{
return;
}
}
}
/// <summary>
/// Checks if the user is authenticated.
/// </summary>
/// <returns>True if the user is authenticated, otherwise false.</returns>
private bool IsUserAuthenticated()
{
return LoginForm.IsAuthenticated;
}
/// <summary>
/// Handles the "All Funds" button click on the Ribbon.
/// Displays a pop-up with information about all available funds.
/// </summary>
public void OnAllFunds(Microsoft.Office.Core.IRibbonControl control)
{
//As per client requirement need to disable authinticate functionality.
//if (!LoginForm.IsAuthenticated)
//{
// MessageBox.Show("You must be logged in to access this functionality.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// return; // Exit the method since the user is not authenticated
//}
ShowAllFundsPopup();
}
/// <summary>
/// Handles the "Available Fields" button click on the Ribbon.
/// Displays a pop-up with information about available fields.
/// </summary>
public void OnAvailableFields(Microsoft.Office.Core.IRibbonControl control)
{
//As per client requirement need to disable authinticate functionality.
//if (!LoginForm.IsAuthenticated)
//{
// MessageBox.Show("You must be logged in to access this functionality.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// return;
//}
var popup = new AvailableFieldsPopup();
popup.ShowDialog();
}
/// <summary>
/// Handles the "Show Version" button click on the Ribbon.
/// Displays the add-in version information.
/// </summary>
public void OnShowVersion(Microsoft.Office.Core.IRibbonControl control)
{
const string projectVersion = "1.0.3";
MessageBox.Show($"BanorCapital Add-In Version: {projectVersion}", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// Handles the "User Manual" button click on the Ribbon.
/// Displays the user manual form.
/// </summary>
public void OnUserManual(Microsoft.Office.Core.IRibbonControl control)
{
var userManualForm = new UserManualForm();
userManualForm.ShowDialog();
}
/// <summary>
/// Retrieves the dynamic status image based on user authentication and flag status.
/// </summary>
/// <param name="control">The Ribbon control requesting the image.</param>
/// <returns>A System.Drawing.Bitmap representing the dynamic status.</returns>
public System.Drawing.Bitmap GetDynamicStatus(Microsoft.Office.Core.IRibbonControl control)
{
string username = LoginForm.AuthenticatedUsername;
if (string.IsNullOrEmpty(username))
{
string defaultImagePath = "Images//LogoutUser.png";
return new System.Drawing.Bitmap(defaultImagePath);
}
bool flagStatus = FetchFlagStatusFromEndpoint(username, timezone);
string imagePath = flagStatus ? "Images//LoginUser.png" : "Images//LogoutUser.png";
System.Drawing.Bitmap image = new System.Drawing.Bitmap(imagePath);
return image;
}
/// <summary>
/// Disposes of resources used by the RibbonController.
/// </summary>
public void Dispose()
{
}
}
}
=======
<?xml version="1.0" encoding="utf-8"?>
<DnaLibrary Name="BanorCapital Add-In" RuntimeVersion="v4.0" xmlns="
http://schemas.excel-dna.net/addin/2020/07/dnalibrary">
<ExternalLibrary Path="BanorCapital.dll" ExplicitExports="false" LoadFromBytes="true" Pack="true" IncludePdb="false" />
<CustomUI>
<customUI xmlns='
http://schemas.microsoft.com/office/2009/07/customui' loadImage='LoadImage' onLoad='OnLoad'>
<ribbon>
<tabs>
<tab id='sample_tab' label='Banorcapital'>
<group id='sample_group' label='Operations'>
<button id='all_funds' label='Fund List' size='large' onAction='OnAllFunds' image='AllFunds'/>
<button id='fetch_data' label='Portfolio Data' size='large' onAction='OnFetchData' image='PortFolio'/>
<button id='available_fields' label='Available Fields' size='large' onAction='OnAvailableFields' image='CustomAvailableFields'/>
</group>
<group id='database_group' label='Data Sources'>
<checkBox id='checkbox_sql' label='SQL'
onAction='OnCheckBoxSql'
getPressed='GetCheckBoxSqlPressed'
screentip='Select SQL data source'
supertip='Select this option to fetch data from an SQL database'/>
<checkBox id='checkbox_influx' label='Influx'
onAction='OnCheckBoxInflux'
getPressed='GetCheckBoxInfluxPressed'
screentip='Select InfluxDB data source'
supertip='Select this option to fetch data from InfluxDB'/>
<checkBox id='checkbox_bpipe' label='B-Pipe'
onAction='OnCheckBoxBPipe'
getPressed='GetCheckBoxBPipePressed'
screentip='Select B Pipe data source'
supertip='Select this option to fetch data from B Pipe'/>
</group>
<group id='dynamic_group' label='B-Pipe App'>
<button id='status_button' label='Status' size='large' onAction ='OnBpipeStatus' getImage='GetDynamicStatus'/>
</group>
<group id='setting_group' label='Settings'>
<button id='settings_button' label='Settings' size='large' onAction='OnSettings' image='Settings'/>
</group>
<group id='info_group' label='Info'>
<button id='user_manual_button' label='Help' size='large' onAction='OnUserManual' image='UserManual'/>
<button id='version_button' label='Version' size='large' onAction='OnShowVersion' image='VersionIcon'/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
</CustomUI>
<Image Name='PortFolio' Path='Images\PortFolio.png' Pack='true' />
<Image Name='CustomAvailableFields' Path='Images\AvailableFields.png' Pack='true' />
<Image Name='AllFunds' Path='Images\AllFunds.png' Pack='true' />
<Image Name='Settings' Path='Images\Settings.png' Pack='true' />
<Image Name='VersionIcon' Path='Images\VersionIcon.png' Pack='true' />
<Image Name='UserManual' Path='Images\UserManual.png' Pack='true' />
<Image Name='SQLIcon' Path='Images\SQLIcon.png' Pack='true' />
</DnaLibrary>