因工作需要读取Paradox数据,且定期将数据导入到MSSQL中,要求在多台机上运行,且不影响用户操作电脑。 后决定用C#,开发系统服务的方式,主导数程序要支持自动更新,下将费了我点时间的技术点记下以备不时之需:
1、Paradox数据的读取
连接代码,连接后一张表就是一个文件,关联查询不知可不可以,没试。
OleDbConnection ConnS = new OleDbConnection();
ConnS.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\TmpDB;Extended Properties=Paradox 5.x; Persist Security Info=true";
查询条件时注意日期,这样可以查:LoadTime>=format('2012/02/01','yyyy/mm/dd')
一般表只有两个文件*.db,*.px,此情况可直接查询;有些表有很多文件,如*.xgo,这时 查询时会出错的,但可以将两个文件拷到其它地方,这样就可以查询了,也不知什么原因,怀疑多出来的文件是加密用的。
2、系统服务方面的开发
public SerMain()
{
InitializeComponent();
//1000毫秒为 1 秒, 半个钟为1800000毫秒
timer = new System.Timers.Timer(1800000);//实例化Timer类,设置间隔时间为半个种;
timer.Elapsed += new System.Timers.ElapsedEventHandler(TimeElapse);//到达时间的时候执行事件;
timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
timer.Enabled = false;//是否执行System.Timers.Timer.Elapsed事件;
}
int runtimers = 30;
protected override void OnStart(string[] args)
{
clsP.IPInfo = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName())[0].ToString();
clsP.SiteNo = System.Configuration.ConfigurationManager.AppSettings["SiteNo"].ToString();
clsP.SourceFile = System.Configuration.ConfigurationManager.AppSettings["SourceFile"].ToString();
clsP.db_server = System.Configuration.ConfigurationManager.AppSettings["DB_Server"].ToString();
clsP.db_db = System.Configuration.ConfigurationManager.AppSettings["DB_Database"].ToString();
clsP.db_user = System.Configuration.ConfigurationManager.AppSettings["DB_User"].ToString();
clsP.db_psw = System.Configuration.ConfigurationManager.AppSettings["DB_Psw"].ToString();
Security sec = new Security();
clsP.db_user = sec.Passport_Decrypt(clsP.db_user);
clsP.db_psw = sec.Passport_Decrypt(clsP.db_psw);
clsP.MailFrom = System.Configuration.ConfigurationManager.AppSettings["MailFrom"].ToString();
clsP.MailTo = System.Configuration.ConfigurationManager.AppSettings["MailTo"].ToString();
clsP.ImportVoidForDll();
GC.Collect();
runtimers = Convert.ToInt16(System.Configuration.ConfigurationManager.AppSettings["RunTimers"].ToString());
timer.Interval = runtimers * 60 * 1000;
timer.Enabled = true;
}
protected override void OnStop()
{
timer.Enabled = false;
}
public void TimeElapse(object source, System.Timers.ElapsedEventArgs e)
{
timer.Enabled = false;
clsP.ImportVoidForDll();
GC.Collect();
runtimers = Convert.ToInt16(System.Configuration.ConfigurationManager.AppSettings["RunTimers"].ToString());
timer.Interval = runtimers * 60 * 1000;
timer.Enabled = true;
}
3、清除反谢调用所加的dll
try
{
string callingDomainName = AppDomain.CurrentDomain.FriendlyName;
AppDomain ad = AppDomain.CreateDomain("ClassImport");
ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(Application.StartupPath + "\\WinServiceWeigth.exe", "WinServiceWeigth.ProxyObject");
obj.LoadAssembly(Application.StartupPath + "\\ClassImport.dll");
obj.Invoke("WinServiceWeigth.clsP", "ImportVoid");
AppDomain.Unload(ad);
obj = null;
}
catch (Exception ex)
{
Mail.New().SendMail(clsP.MailFrom, clsP.MailTo, "", "磅重导数程序", clsP.IPInfo + " 上的服务导数程序出错了; 调用dll出错:" + ex.ToString());
}
要注意此类, 要继承MarshalByRefObject
才可以清除的。
class ProxyObject : MarshalByRefObject
{
Assembly assembly = null;
public void LoadAssembly(string strPath)
{
assembly = Assembly.LoadFile(strPath);
}
public bool Invoke(string fullClassName, string methodName)
{
if (assembly == null)
return false;
Type tp = assembly.GetType(fullClassName);
if (tp == null)
return false;
MethodInfo method = tp.GetMethod(methodName);
if (method == null)
return false;
Object obj = Activator.CreateInstance(tp);
method.Invoke(obj, null);
return true;
}
}