2017-03-02 2 views
0

Das Problem, das ich hier renne, ist, dass ich eine kombinierte COM und Automation Add In für Excel erstellen. Bei dem Versuch, auf Properties.Settings.Default in der von mir erstellten Klasse Automation Add In zuzugreifen, sind die Werte, die ich als Standardwerte für das Projekt festgelegt habe, obwohl das COM Add In Werte zurückgibt, die über ein Konfigurationsformular gespeichert worden sind .Visual Studio C# Properties.Settings.Default Probleme

Alle Klassen befinden sich im selben Projekt und unter demselben Namespace, und die Klassendateien für mein Konfigurationsformular, COM-Add-In und Multifunktionsleiste können alle auf die aktualisierten Properties.Settings.Default-Werte zugreifen. Mein Automation Add-In und eine statische Klasse (die alle schweren Aufgaben bewältigt) können nicht auf die aktualisierten Werte zugreifen.

COM Add-In:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using Excel = Microsoft.Office.Interop.Excel; 
using Office = Microsoft.Office.Core; 
using Microsoft.Office.Tools.Excel; 
using System.Windows.Forms; 

namespace DBLink 
{ 
    public partial class ThisAddIn 
    { 
     //public Dictionary<string, string> reports; 
     private void ThisAddIn_Startup(object sender, System.EventArgs e) 
     { 
      MessageBox.Show("User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "); 
     } 

     private void ThisAddIn_Shutdown(object sender, System.EventArgs e) 
     { 
     } 

     #region VSTO generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InternalStartup() 
     { 
      this.Startup += new System.EventHandler(ThisAddIn_Startup); 
      this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 
     } 

     #endregion 
    } 
} 

Ribbon:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Data; 
using System.Data.SqlClient; 
using Microsoft.Office.Tools.Ribbon; 
using Excel = Microsoft.Office.Interop.Excel; 
using Microsoft.Office.Tools.Excel; 

namespace DBLink 
{ 
    public partial class Ribbon1 
    { 
     private void Ribbon1_Load(object sender, RibbonUIEventArgs e) 
     { 
      //Even setting the connection string from a class that has 
      //access to the correct values fails and says the connection 
      //string is not initialised. 
      string conString; 
      conString = "User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "; 
      DataLink.connString = conString; 

      MessageBox.Show("User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "); 
     } 

     private void button1_Click(object sender, RibbonControlEventArgs e) 
     { 
      Form frm = new Form1(); 
      frm.ShowDialog(); 
     } 

     private void button2_Click(object sender, RibbonControlEventArgs e) 
     { 
      try 
      { 
       DataLink.LoadData(Globals.ThisAddIn.Application.ActiveWorkbook); 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message.ToString()); 
      } 
     } 

     private void button5_Click(object sender, RibbonControlEventArgs e) 
     { 
      //Do Stuff 
     } 

     private void button3_Click(object sender, RibbonControlEventArgs e) 
     { 
      //Do Stuff 
     } 
    } 
} 

Form:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Data.SqlClient; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Windows.Forms; 

namespace DBLink 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      Properties.Settings.Default.DBServer = textBox1.Text; 
      Properties.Settings.Default.DBName = textBox2.Text; 
      Properties.Settings.Default.DBUser = textBox3.Text; 
      Properties.Settings.Default.DBPassword = textBox4.Text; 
      Properties.Settings.Default.Save(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      SqlConnection con = new SqlConnection("User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "); 
      try 
      { 
       con.Open(); 
       MessageBox.Show("Connected successfully"); 
       con.Close(); 
      } 
      catch 
      { 
       MessageBox.Show("There was a problem connecting to the database. Please confirm the details!"); 
      } 
     } 
    } 
} 

Automation:

using System; 
using System.Runtime.InteropServices; 
using Microsoft.Win32; 

namespace DBLink 
{ 
    [Guid("19C7ACDB-1572-4988-984F-3C56AEF117A5")] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ComVisible(true)] 

    public partial class MyFunctions2 
    { 
     string connectionString; 
     public MyFunctions2() 
     { 
     } 

     private static string GetSubKeyName(Type type, string subKeyName) 
     { 
      System.Text.StringBuilder s = new System.Text.StringBuilder(); 
      s.Append(@"CLSID\{"); 
      s.Append(type.GUID.ToString().ToUpper()); 
      s.Append(@"}\"); 
      s.Append(subKeyName); 
      return s.ToString(); 
     } 
     public string MTD(int year, int period, string costCentre, string account) 
     { 
      connectionString = "User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "; 
     return DataLink.MTD(year, period, costCentre, account, connectionString).ToString(); 
     } 

     public double MultiplyNTimes2(double number1, double number2, double timesToMultiply) 
     { 
      return DataLink.MultiplyNTimes(number1, number2, timesToMultiply); 
     } 

     [ComRegisterFunctionAttribute] 
     public static void RegisterFunction(Type type) 
     { 
      Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable")); 
      RegistryKey key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true); 

      key.SetValue("", System.Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String); 
     } 

     [ComUnregisterFunctionAttribute] 
     public static void UnregisterFunction(Type type) 
     { 
      Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false); 
     } 
    } 
} 

Schließlich ist die statische Klasse:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Data; 
using System.Data.SqlClient; 
using Microsoft.Office.Tools.Ribbon; 
using Excel = Microsoft.Office.Interop.Excel; 

namespace DBLink 
{ 
    public static partial class DataLink 
    { 
     private static string commandText = "select case when ACClass in (2,3,4,5) then SUM(ISNULL(POCredit,0)-ISNULL(PODebit,0)) else SUM(ISNULL(PODebit,0)-ISNULL(POCredit,0)) end as value from Account join Post on ACID = POAccountID left join Segment on SID = POSegmentID join Journal on POJournalID = JID where DatePart(month,JDate) = @month and DatePart(year,JDate) = @year and ACCode = @account and (SName = @seg or @seg = '*') group by ACClass"; 
     public static string connString=""; 
     private static SqlConnection con; 

     public static void SetConnString(string connection) 
     { 
      connString = connection; 
     } 
     public static void LoadData(Excel.Workbook wb) 
     { 
      //Do stuff... may be deprecated before release. 
     } 

     public static double MTD(int year, int period, string costCentre, string account, string conString) 
     { 
      DataTable dt = new DataTable(); 
      DataSet ds = new DataSet(); 
      double result = 0; 
      int month = period > 6 ? period - 6 : period + 6; 
      int actualYear = month > 6 ? year - 1 : year; 

      MessageBox.Show("User ID = " + Properties.Settings.Default.DBUser + "; Password = " + Properties.Settings.Default.DBPassword + "; Data Source = " + Properties.Settings.Default.DBServer + "; Initial Catalog = " + Properties.Settings.Default.DBName + "; "); 

      con = new SqlConnection(connString); 
      try 
      { 
       using (SqlCommand cmd = new SqlCommand(commandText, con)) 
       { 
        cmd.Parameters.AddWithValue("@month", month); 
        cmd.Parameters.AddWithValue("@year", actualYear); 
        cmd.Parameters.AddWithValue("@account", account); 
        cmd.Parameters.AddWithValue("@seg", costCentre); 
        MessageBox.Show(cmd.CommandText); 
        MessageBox.Show(cmd.Connection.ConnectionString); 
        cmd.Connection.Open(); 
        dt.Load(cmd.ExecuteReader()); 
        if (dt.Rows.Count > 0) 
        { 
         MessageBox.Show("We have a row"); 
         ds.Tables.Add(dt); 
         result = double.Parse(ds.Tables[0].Rows[0].ItemArray[0].ToString()); 
        } 
        cmd.Connection.Close(); 
        MessageBox.Show(result.ToString()); 
       } 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message.ToString()); 
      } 

      return result; 
     } 
    } 
} 

Alles, was ich denken kann, ist, dass irgendwie zwei oder mehr Instanzen der Einstellungen erstellt werden. Wenn jemand irgendwelche Ideen hat, wie dies gelöst werden könnte, wäre das hervorragend.

EDIT: Spielen über ein bisschen mehr, es scheint, das COM Add-in sieht nur die gespeicherten Werte beim Laden und sieht dann das Original. Das Menüband kann die Einstellungen die ganze Zeit sehen.

EDIT 2: Haben Sie es ausgearbeitet und setzen Sie die Antwort für zukünftige Referenz, wird als Antwort markieren, sobald die 2-Tage-Beschränkung ist.

+0

Sind die Einstellungen in ** ** Benutzer Umfang? und ist die Konfigurationsdatei neben der Assembly? –

+0

@LeiYang ja, die Einstellungen sind im Benutzerbereich (vor Jahren in einem anderen Projekt in dieses Problem geraten). Die Datei DBLink.dll.config.deploy befindet sich neben der Datei DBLink.dll.deploy im versionsgesteuerten Ordner Anwendungsdateien, den Visual Studio generiert, wenn Sie die Veröffentlichungsoption verwenden. Wenn ich Build verwende, erhalte ich eine Datei DBLink.dll.config, die neben DBLink.dll sitzt. – Aaron

Antwort

0

Okay, also habe ich eine Lösung gefunden, da alles in verschiedene AppDomains geladen wurde.

Schritt 1: Rufen Sie in der ThisAddIn_Startup-Methode this.Application.Evaluate("=MTD()"); auf. Das bedeutete, dass sowohl mein COM- als auch das Automatisierungs-Add-In unter derselben AppDomain ausgeführt wurden.

Schritt 2: Übergeben Sie die Verbindungszeichenfolge an meine DataLink-Klasse in der ThisAddIn_Startup-Methode.

Eine riesige Menge an googeln, dass zu finden: https://groups.google.com/forum/#!msg/microsoft.public.office.developer.com.add_ins/_ZP9udZJ7bI/Q9fU6rsGhTcJ