2017-03-02 10 views
0

여기에서 실행중인 문제는 Excel 용 통합 COM 및 자동화 추가 기능을 작성한다는 것입니다. Automation Add In 클래스의 Properties.Settings.Default에 액세스하려고 할 때 COM Add In이 구성 양식을 통해 저장 한 값을 반환하더라도 프로젝트의 기본값으로 설정 한 값이 생성됩니다. .Visual Studio C# Properties.Settings.Default issues

모든 클래스가 동일한 프로젝트에 있고 동일한 네임 스페이스에서 내 구성 양식의 클래스 파일 인 COM 추가 기능 및 리본이 모두 업데이트 된 Properties.Settings.Default 값에 액세스 할 수 있습니다. 내 자동화 추가 기능과 모든 과도한 작업을 처리하는 정적 클래스는 업데이트 된 값에 액세스 할 수 없습니다.

COM 추가 기능 :

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 
    } 
} 

리본 :

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 
     } 
    } 
} 

형태 :

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!"); 
      } 
     } 
    } 
} 

자동화 :

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); 
     } 
    } 
} 

마지막으로, 정적 클래스 :

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; 
     } 
    } 
} 

내가 생각할 수있는 모든 설정의 어떻게 든 2 개 이상의 인스턴스가 생성되고 있다는 점이다. 이것이 해결 될 수있는 방법에 대한 아이디어가있는 사람은 누구나 우수 할 것입니다.

EDIT : COM 추가 기능은로드 할 때 저장된 값만보고 원본을 보는 것처럼 보입니다. 리본은 전체 설정을 볼 수 있습니다.

EDIT 2 : 나중에 참고할 수 있도록 답변 해 주셨습니다. 2 일 제한이 끝나면 답변으로 표시됩니다.

+0

는 ** 사용자 ** 범위의 설정이 있습니까? 그리고 어셈블리 옆에 설정 파일이 있습니까? –

+0

@LeiYang 예, 설정은 사용자 범위에 있습니다 (이전에 다른 프로젝트에서이 문제가 발생했습니다). DBLink.dll.config.deploy 파일은 게시 옵션을 사용할 때 Visual Studio에서 생성되는 버전 제어 Application Files 폴더의 DBLink.dll.deploy 파일 옆에 있습니다. Build를 사용하면 DBLink.dll.config 파일이 DBLink.dll 옆에 있습니다. – Aaron

답변

0

좋아요, 그래서 모든 것이 다른 AppDomains에로드되는대로 해결책을 찾았습니다.

1 단계 : ThisAddIn_Startup 메서드에서 this.Application.Evaluate("=MTD()");을 호출하십시오. 이것은 내 COM 및 자동화 추가 기능이 모두 동일한 AppDomain에서 실행되고 있음을 의미합니다.

2 단계 : ThisAddIn_Startup 메소드의 DataLink 클래스에 연결 문자열을 전달하십시오.

것을 찾기 위해 인터넷 검색의 엄청난 양 : https://groups.google.com/forum/#!msg/microsoft.public.office.developer.com.add_ins/_ZP9udZJ7bI/Q9fU6rsGhTcJ