金蝶的登录界面,主要是COM技术,在.NET4.0之前,我们使用Reflection来调用,而.NET4.0之后,我们可以使用Dynamic特性来调用了。以下是使用.NET2.0来实现的,没有什么好说的,直接上代码,代码就是最好的说明,以下是我封装的一个类:
using System; using System.Collections.Generic; using System.Text; using System.Data.OleDb; using System.Data.SqlClient; namespace System { public class KingdeeLogin { private object _kingdeeLoginObject; private Type _kingdeeLoginType; private string _sqlConnectionString; private string _accountName; private string _userName; private int _userId; public KingdeeLogin() { _kingdeeLoginType = Type.GetTypeFromProgID("K3Login.ClsLogin", true); _kingdeeLoginObject = Activator.CreateInstance(_kingdeeLoginType); _sqlConnectionString = ""; } public bool CheckLogin() { var result = _kingdeeLoginType.InvokeMember("CheckLogin", Reflection.BindingFlags.InvokeMethod | Reflection.BindingFlags.Instance | Reflection.BindingFlags.Public, null, _kingdeeLoginObject, null); bool bResult = (bool)result; if (bResult) { InitialLoginDatas(); } return bResult; } #region 解析金蝶的PROP_STRING private void InitialLoginDatas() { string kingdeePropString = _kingdeeLoginType.InvokeMember("PropsString", Reflection.BindingFlags.GetProperty | Reflection.BindingFlags.Instance | Reflection.BindingFlags.Public, null, _kingdeeLoginObject, null).ToString(); _accountName = _kingdeeLoginType.InvokeMember("AcctName", Reflection.BindingFlags.GetProperty | Reflection.BindingFlags.Instance | Reflection.BindingFlags.Public, null, _kingdeeLoginObject, null).ToString(); ParsePropStringToField(kingdeePropString); } private void ParsePropStringToField(string propString) { var datas = ReadPropStringToDictinary(propString); _userName = GetValueFromDictionay("UserName", datas); _userId = int.Parse(GetValueFromDictionay("UserID", datas)); _sqlConnectionString = ConvertSqlConnectionString(GetValueFromDictionay("ConnectString", datas)); //这里大家可以继续扩展,因为PropsString里面还有很多字段。 } private string ConvertSqlConnectionString(string oleDbConnectionString) { OleDbConnectionStringBuilder oleBuilder = new OleDbConnectionStringBuilder(oleDbConnectionString); SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder(); sqlBuilder.UserID = oleBuilder["User ID"].ToString(); sqlBuilder.Password = oleBuilder["Password"].ToString(); sqlBuilder.DataSource = oleBuilder["Data Source"].ToString(); sqlBuilder.InitialCatalog = oleBuilder["Initial Catalog"].ToString(); object IntegratedSecurity; if (oleBuilder.TryGetValue("Integrated Security", out IntegratedSecurity)) { if (IntegratedSecurity.ToString().ToUpper() == "SSPI") { sqlBuilder.IntegratedSecurity = true; } } else { sqlBuilder.IntegratedSecurity = false; } return sqlBuilder.ConnectionString; } private Dictionary<string, string> ReadPropStringToDictinary(string propString) { Dictionary<string, string> result = new Dictionary<string, string>(); int curIndex = 0; while (curIndex < propString.Length) { curIndex += ReadSection(result, propString.Substring(curIndex)); } return result; } private int ReadSection(Dictionary<string, string> sections, string source) { int lengthResult = 0; string key = ""; string value = ""; lengthResult += ReadKey(source, out key); lengthResult += ReadValue(source.Substring(lengthResult), out value); sections.Add(key, value); return lengthResult; } private int ReadKey(string source, out string key) { key = ""; int lengthResult = 0; for (int i = 0; i < source.Length; i++) { lengthResult = i + 1; if (source[i] == '=') { break; } else { key += source[i]; } } return lengthResult; } private int ReadValue(string source, out string value) { value = ""; int lengthResult = 0; Stack<char> charStack = new Stack<char>(); for (int i = 0; i < source.Length; i++) { char c = source[i]; lengthResult = i + 1; if (c == '{') { if (charStack.Count > 0) value += c; charStack.Push(c); } else if (c == '}') { charStack.Pop(); if (charStack.Count > 0) value += c; } else if (c == ';') { if (charStack.Count > 0) { value += c; } else { break; } } else { value += c; } } return lengthResult; } private string GetValueFromDictionay(string key, Dictionary<string, string> source) { string dicKey = ""; foreach (string sKey in source.Keys) { if (key.Trim().ToUpper() == sKey.Trim().ToUpper()) { dicKey = sKey; break; } } if (string.IsNullOrEmpty(dicKey)) return string.Empty; return source[dicKey]; } #endregion public string SqlConnectionString { get { return _sqlConnectionString; } } public string AccountName { get { return _accountName; } } public string UserName { get { return _userName; } } public int UserID { get { return _userId; } } } }
调用方式如下:
static class Program { public static string SqlConnectionString = ""; public static string AccountName = ""; public static string LoginUserName = ""; /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!InitialConnectionString()) return; Application.Run(new FrmMain()); } static bool InitialConnectionString() { try { KingdeeLogin clsLogin = new KingdeeLogin(); if (clsLogin.CheckLogin()) { SqlConnectionString = clsLogin.SqlConnectionString; AccountName = clsLogin.AccountName; LoginUserName = clsLogin.UserName; if (!TestConnectionString(SqlConnectionString)) { MessageBox.Show("无法连接到服务器数据库,请确保服务器端的防火墙没有屏蔽相应端口!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; } return false; } catch { MessageBox.Show("只能在安装了金蝶客户端的机器上运行!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } static bool TestConnectionString(string connectionString) { try { SqlConnection connection = new SqlConnection(connectionString); connection.Open(); connection.Close(); return true; } catch { return false; } } }
希望能帮助到那些用c#做金蝶二次开发的。