近日wow非官方出了一个新的插件,给牧师或其他辅助职业用的,安装设置后可以一键选择治疗使用的魔法,亦可以选择给队友驱散魔法还是驱散疾病。这个插件当然也不是属于外挂的范畴,因为它完全按照官方给出的UI来开发的。但是使用了之后,对于一个完全不懂牧师或者其他辅助职业的玩家来说,就相当的easy了,简直就是傻瓜透了的插件。这样玩家就根本不需要去理解职业,个人还是不支持如此的插件。
对于.NET 2.0我一直都不感冒,对于有些变化虽然是道听途说,但是我也不太支持。今天偶然看到ASP.NET 2.0 的内部变化,其中对于2.0中代码模型的描述——“ 代码隐藏文件可以自动访问 ASPX 页上的任何控件,而不需要 ASP.NET 1.x 中所需的声明代码。所有这些都是可能的,因为 ASP.NET 运行库自动将所需要的声明和事件连接代码插入到最终的已编译文件中。”。对于2.0的代码模型我觉得这个改进还是很不错的,但是对于由此产生的优点,使用当然方便了,完全不需要自己来管,降低了门槛自然不用说,可对于C#这种强类型语言来说,是不是不太恰当?
和wow非官方出的这个插件是否有几分相似?
对于编译方法,改进还是很诱人的。至少看了这篇文章,让孤陋寡闻的我了解到1.x中还有种批编译的方式,只需要在web.config中加入如下代码(更多的还是看ms-help://MS.NETFrameworkSDKv1.1.CHS/cpgenref/html/gngrfcompilationsection.htm)——
1<compilation
2 batch="true|false"
3 batchTimeout="number of seconds"
4 maxBatchSize="maximum number of pages per batched compilation"
5 maxBatchGeneratedFileSize="maximum combined size (in KB) of the
6 generated source file per batched compilation" >
7</compilation>
总的说来,2.0的变化还是不错的,当然除了上面我提出的那一点(个人看法)。至于winform的变化,欣喜的东西好像更多一点点。但我觉得微软就是这样,本来可以这个版本做到的,他就不做,比如说office2000中选择字体就不能看到字体的样式,而到了office XP,就可以了。也许这就是软件公司的策略。如果是我也许也会这么做。
但是对于那种傻瓜式的改进我还是不赞同,不管是.NET,还是wow插件。
这次的项目整个都比较正规,所以即便是web的,也需要制作完整的安装文件,首先我想到的是InstallShield或者installanywhere。
先是installanywhere,尝试自己做了一下,好像功能有点弱,所以没有继续研究,转而去下了个InstallShield 10,集成到VS.NET中,虽然可以按照向导一步一步走,但是最后得到的结果还是让我不满意。所以决定还是用VS.NET。
网上放狗一搜,发现很多可用资源,现在都列出几个——
1、部署ASP.NET的三大技术;
2、部署.net平台的程序;
3、.NET平台下WEB应用程序的部署(安装数据库和自动配置) ;
第三个也就是很重要的,一般来说web项目都需要建立数据库,所以我就主要参考了这个文档,对其中给出的VB.NET代码改造为C#(这个让我很头疼了一会儿,这里要感谢GoodIdea、大鱼、小峰的帮助),在此我给出我调试好的C#代码(其中加入了如果创建数据库时存在同名的数据库会自动drop掉)——
1 using System;
2 using System.Collections;
3 using System.ComponentModel;
4 using System.Configuration.Install;
5 using System.IO;
6 using System.Reflection;
7 using System.Diagnostics;
8 //using System.Data;
9 //using System.Data.SqlClient;
10
11 namespace DBCustomAction
12 {
13 /// <summary>
14 /// DBCustomAction 的摘要说明。
15 /// </summary>
16 [RunInstaller(true)]
17 public class DBCustomAction : System.Configuration.Install.Installer
18 {
19 /// <summary>
20 /// 必需的设计器变量。
21 /// </summary>
22 private System.ComponentModel.Container components = null;
23
24 public DBCustomAction()
25 {
26 // 该调用是设计器所必需的。
27 InitializeComponent();
28
29 // TODO: 在 InitializeComponent 调用后添加任何初始化
30 }
31
32 &nbs
p; /// <summary>
33 /// 清理所有正在使用的资源。
34 /// </summary>
35 protected override void Dispose( bool disposing )
36 {
37 if( disposing )
38 {
39 if(components != null)
40 {
41 components.Dispose();
42 }
43 }
44 base.Dispose( disposing );
45 }
46
47
48 #region 组件设计器生成的代码
49 /// <summary>
50 /// 设计器支持所需的方法 – 不要使用代码编辑器修改
51 /// 此方法的内容。
52 /// </summary>
53 private void InitializeComponent()
54 {
55 components = new System.ComponentModel.Container();
56 }
57 #endregion
58
59 //执行SQL 语句
60 private void ExecuteSql(string conn,string DatabaseName,string sql)
61 {
62 System.Data.SqlClient.SqlConnection mySqlConnection = new System.Data.SqlClient.SqlConnection
(conn);
63 System.Data.SqlClient.SqlCommand Command = new System.Data.SqlClient.SqlCommand(sql,mySqlConnection);
64 Command.Connection.Open();
65 Command.Connection.ChangeDatabase(DatabaseName);
66 try
67 {
68 Command.ExecuteNonQuery();
69 }
70 finally
71 {
72 Command.Connection.Close();
73 }
74 }
75
76 public override void Install(System.Collections.IDictionary stateSaver)
77 {
78 //————————建立数据库————————————————-
79 try
80 {
81 string connStr = string.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096", this.Context.Parameters["server"],this.Context.Parameters["user"], this.Context.Parameters["pwd"]);
82 //根据输入的数据库名称建立数据库
83 //如果输入库存在先删除
84 string checkDatabase = "if exists (select name from master..sysdatabases where name=’" + this.Context.Parameters["dbname"] + "‘) drop database " + this.Context.Parameters["dbname"];
85 &n
bsp; ExecuteSql(connStr,"master",checkDatabase);
86 //创建新的数据库
87 ExecuteSql(connStr,"master","CREATE DATABASE " + this.Context.Parameters["dbname"]);
88 //调用osql执行脚本
89 System.Diagnostics.Process sqlProcess = new Process();
90 sqlProcess.StartInfo.FileName = "osql.exe";
91 sqlProcess.StartInfo.Arguments = string.Format(" -U {0} -P {1} -d {2} -i {3}db.sql", this.Context.Parameters["user"], this.Context.Parameters["pwd"], this.Context.Parameters["dbname"], this.Context.Parameters["targetdir"]);
92 sqlProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
93 sqlProcess.Start();
94 sqlProcess.WaitForExit(); //等待执行
95 sqlProcess.Close();
96 //删除脚本文件
97 System.IO.FileInfo sqlFileInfo = new FileInfo(string.Format("{0}db.sql", this.Context.Parameters["targetdir"]));
98 if (sqlFileInfo.Exists)
99 {
100 sqlFileInfo.Delete();
101 }
102
>103 }
104 catch(Exception ex)
105 {
106 throw ex;
107 }
108
109 // ———————将连接字符串写入Web.config———————————–
110 try
111 {
112 System.IO.FileInfo FileInfo = new FileInfo(this.Context.Parameters["targetdir"] + "\\web.config");
113 if (!FileInfo.Exists)
114 {
115 throw new InstallException("没有找到配置文件");
116 }
117
118 //实例化XML文档
119 System.Xml.XmlDocument XmlDocument = new System.Xml.XmlDocument();
120 XmlDocument.Load(FileInfo.FullName);
121 //查找到appSettings中的节点
122 bool FoundIt = false;
123 //XmlNode root = XmlDocument.FirstChild;
124 //System.Xml.XmlNode appNode = XmlDocument.SelectSingleNode("configuration").SelectSingleNode("appSettings");
125 foreach ( System.Xml.XmlNode n in XmlDocument.SelectSingleNode("configuration").SelectSingleNode("appSettings"))
126 {
127 &nb
sp; if ( n.Name == "add" )
128 {
129 if ( n.Attributes["key"].Value == "dsn" )
130 {
131 n.Attributes["value"].Value = string.Format("Persist Security Info=False;Data Source={0};Initial Catalog={1};User ID={2};Password={3};Packet Size=4096;Pooling=true;Max Pool Size=100;Min Pool Size=1",this.Context.Parameters["server"], this.Context.Parameters["dbname"], this.Context.Parameters["user"], this.Context.Parameters["pwd"]);
132 FoundIt = true;
133 }
134 }
135 }
136 if (!FoundIt)
137 {
138 throw new InstallException("web.Config 文件没有包含dsn连接字符串设置");
139 }
140 XmlDocument.Save(FileInfo.FullName);
141 }
142 catch(Exception ex)
143 {
144 throw ex;
145 }
146 }
147 }
148 }
149
之后,只要去下载一个Microsoft Visual Studio .NET 2003 引导程序插件,生成安装项目就可以了。整个安装程序实现的功能如下——
1、安装时侦测客户的服务器是否安装了.NET框架,如果没有安装,会自动提示安装;
2、安装程序自动侦测客户服的务器的MDAC版本是否是达到需要,如果没有,自动安装;
3、安装程序自动按照用户要求创建数据库,并建立站点虚拟目录;
其它制作安装程序的步骤,上面我给出的文档都已经说得很详细了,为一的不足,就是让用户填入数据库用户的密码时,是直接显示的,而不是隐藏的,我也正在找如何解决这个问题。
记得我在今年上半年写过一篇从Adware想到共享软件开发的focus问题,曾经就FlashGet中加入Adware引起如今很多杀毒软件的查杀。昨天因为最近常无故死机重装系统,以为Thunder和FlashGet一样绿色,但是居然不能使用了。所以准备去下载站点下一个,就发现了更新的FlashGet 1.71。
说句实话,我还是很喜欢FlashGet的,虽然曾经有段时间因为Adware问题不再使用,但是我从NetAnt到FlashGet,而使用最长的就是FlashGet,不仅下载速度让我满意(记得大学时曾经在拨号方式,使用NetAnt和FlashGet下载同一个文件,结果测试了三次,均是FlashGet好一点点),而且每次重装后不需要我再安装。而在我抛弃FlashGet三个月之后,我抱着尝试的态度下了最新版的。
安装( 我的VirusScan仍然 加载了反间谍程序的模块),一切正常!我还是不死心,来到 FlashGet目录,使用VirusScan 再次查了一次,没有发现问题!赫赫,看来FlashGet作者也意识到问题所在,有所改进了。接着,我来到FlashGet的主页,郝然写着这样的字样——
无广告免费
请下载FlashGet 1.71 正式版
确实,无论你是否注册,只要你安装了FlashGet如今这个1.71版,确实再也看不到任何的广告。相比Thunder,铺天盖地的广告来得更清爽。看来FlashGet确实回归了,很高兴!
为了避免被误以为是FlashGet的托儿之前,还是申明一下,我纯粹一个爱好者,和FlashGet站点及作者没有任何干系,请不要妄加揣测,谢谢。
继续项目,虽然项目在继续,可我对PetShopDNG的疑问还是很多,也就无法指导下面的学生,问题的关键就是使用了O/R Mapper的工具Data Tier Modeler(简称DTM),PetShopDNG采用DTM的哪个版本生成的数据访问层呢,估计是如今的3.02以前的版本,因为在DAL层和BLL层中间多了些使用Decorator模式的代码,费了多番的周折,才明白如今使用DTM3.02完全可以不再写使用Decorator模式的那些代码。就此反映出来的问题有:
1、自己对模式还不够了解,想学很久了,看了没去用等于白看;
2、对源代码分析能力太低,首先读文档还不够仔细,其次才是代码分析(因为是工具生成的代码,虽然整体架构清晰了,但是要具体分析生成的代码还是一件很头大的事情)。
接着说O/R Mapper,虽然从英文字面上理解了,但是说到实际还是不明白,所以一Google,发现火炬的文章到底什么是O/RMapper。好像正如火炬文章所说DTM就是前者——“ 一些不成熟的(大多是FREE的)用xml文件来定义对象和数据库的mappings,另一些用自定义属性完成。”但是没有办法,这种半截子的项目,我接到了也不能推翻以前领导者的架构,只能硬着头皮上。虽然个人认为这样的架构有好处,但是没有考虑到项目组内成员的水平。因此,这就是第二个大问题——
需要熟悉O/R Mapper的方方面面。
还有就是接口,这个暑假有幸给02级计科系实习的学生讲.NET,短短的一周课,然后让他们做一个图书管理系统,管理部分用c/s模式,读者部分用b/s模式,也就是我们学校图书馆管理系统的翻版。在指导学生的过程中,有一个小组的学生,可能因为基础好,整个项目居然使用了5层,我当时一看就有点晕,然后仔细一看,有了个接口层,当时我就说他们做的太复杂,后来回头一想,他们这是为了锻炼,最后他们那个组的设计还得了实习的奖。回过头来想想自己,接口不熟悉,又是一个知道个大概,这就成了第三个问题——
接口问题。
短短两个月不到的时间发现这么几个大问题,还是够头疼的,还好我向来对问题都比较喜欢,特别是要用到,而自己又不熟悉的东西,所以现在只能让自己恶搞一下,看看有没有成效。不过话说回来,另外还有一个问题就是架构,作为一个项目组小头头,如何确定项目的架构也是需要水平的。忽然想起发仔广告上的一句话——成功?我才刚起步呢!发仔够成功了吧,他都刚起步,我们这些没有成功的年轻人算什么,还是起步吧~~~
昨天说到接手一个半途项目,进度当然非常让人不满意,加上余下时间不多。我昨晚召集项目组内人开了个会,讨论了使用的PetShopDNG的架构,因为组内人都是学生,理解也一知半解。我昨天花了一天的时间了解了项目的具体进度以及已经完成的工作,下午在查看他们的ER图时发现了问题,所以决定开这个会,主要给组内成员理清楚了架构。
昨天写Blog的时候没有看过PetShopDNG的代码,那个时候自己也还不了解架构,后来为了开会,大致研究了一下——
数据访问层不说了,使用DTM生成。关键是业务逻辑层,采用了抽象工厂和单态模式,为了什么呢?为了判断用户需要访问的页面到底载入哪个UserControl。而UserControl的业务逻辑基本都写入UserCommand。
本来最开始,我一看数据访问层使用DTM来生成就对PetShopDNG产生了一点疑惑,但是如今看来,这种做法,还是不错的,当然不是说数据访问层的生成,而是整个的架构,很清晰。
但是,一看上来就是模式,虽然喊了那么久,而我却从来没有认真去看过书之类的,有点懵。所以上午大概看了看几种常用的模式,感觉却是如gr所说,比较的简单。但是实际应用可不那样了,如果没有一定的沉淀,使用模式可能就会很别扭。当然说简单,也就是从纯理论的高度来说,光看没问题,理解起来也容易。
虽然这个项目目前详细设计都还有些许工作没有完成,但是我觉得剩下的时间编码和测试应该没有什么问题。
如愿以偿来到一个新的环境。采用简单的CMM2做的,开发管理都相对我以往的环境要规范很多,我开始以为是CMM2的不熟悉,所以恶补了两天CMM2的东西。来了才发现不是这个问题。
来接到一个未完成的网站项目,其实做网站我还是比较擅长的,关键的问题出在什么地方呢?这个项目采用PetShopDNG的方式,使用了O/R MAPPING工具DTM来做DAL层,所有的工作都要求在此基础上。网站架构也和PetShopDNG一样,一个DAL层,之上是定义的一个BLL层,接下来是UserCommands和UserControls进行交互。aspx文件很少。叫了一帮生手的学生来做,已经作了一个多月,还在详细设计阶段,文档要求当然就是CMM2那样规范。而学生并不够了解PetShopDNG的架构,而项目时间还有两个周…………而我又一次的成为了学生头头儿,呵呵
这么看来我只有恶补这个DTM怎么使用了,有点郁闷。从来没有使用工具生成DAL层,本来是让工作更轻松的工具反而让我很不适应。也不知道这样做是好还是坏。不过能接触到新的东西,而且可以进一步的学习,还是有些幸喜的。再说O/R MAPPING火了也不是一天两天了,能在实际工作中接触到,还是很不错的,至少这个项目完,我可以了解这些O/R MAPPING工具怎么使用,而至于其中的架构还是暂时放放。项目优先阿~~~