分享
 
 
 

没头没尾--项目开发笔记:如何开发代码更新工具?!(下)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

(接上篇http://www.csdn.net/develop/article/16/16299.shtm

Ø 代码更新的替换过程

代码的更新的过程主要是搜索对应的文件的目录,将所有的目标文件找出,将目标文件读入字符串,根据模板文件内容对目标文件进行处理。下面是个简单说明:

1.读入输入模板文件,读出TemplateTag,读出各个CodeSession存入对应的数据结构中;

2.扫描输入的原始文件目录,进行扫描,将符合替换条件的文件找出,调用代码更新的模板;

3.将文件读入内存,查找其中有没有TemplateTag的内容,如果没有查找结果为False,则调用第4步,如果查找结果为True,直接调用第5步;

4.读出各个CodeSession中newsource节中的内容,调用方法修改文件的字符串内容。

然后直接调用第7步;

5.将文件字符串的TemplateTag内容用空字符串替换;

6.读出各个CodeSession中oldsource节中的内容与newsource节中的内容,使用String.Replace的方法将oldsource内容换成newsource内容;

7.将文件字符串加入TemplateTag内容之后重新写回文件之中。

下面是表示此步骤的部分代码:

//GerentorCode函数,代码生成与更新的调用入口

public void GerentorCode()

{

//本函数之前已经将模板文件读入this.TemplateStructure之中,

//其中this.TemplateStructure是一个Dataset类型

//**********************************//

//m_szTagString存入TemplateTag中的内容

m_szTagString = this.TemplateStructure.Tables["CodeTemplate"].Rows[0]["TemplateTag"].ToString();

//遍历CodeSession

foreach(DataRow row in this.TemplateStructure.Tables["CodeSession"].Rows)

{

//分别将对应不用的CodeSession节中的内容取出

//放入不同的函数属性字符串中

if(row["value"].ToString() == "Try")

{

//Try部分要值入的代码

m_szTryString = row["newsource"].ToString();

//Try部分以前值入的旧代码

m_szOldTryString = row["oldsource"].ToString();

}

if(row["value"].ToString() == "Catch")

{

//Catch部分要值入的代码

m_szCatchString = row["newsource"].ToString();

//Catch部分以前值入的旧代码

oldcatchstring = row["oldsource"].ToString();

}

}

//GerentorCode传入路函数径值的函数,

//将会对本路径下所有的Web Service文件进行代码生成或代码更新的处理

GerentorCode(m_szWebServicePath);

}

//GerentorCode函数,代码生成与更新的调用入口

public void GerentorCode(String szPath)

{

//存储文件内容的字符串

string szSourceCode;

//生成目标文件目录的结构

string[] directoryEntries = System.IO.Directory.GetFileSystemEntries(szPath);

//临时字符串

string szTemp;

string szszTemp1;

int nStart;

StreamWriter streamWriter;

StreamReader streamReader;

FileStream sb;

String szReturnType;

//遍历目标文件目录

foreach (String path in directoryEntries)

{

//如果还是目录,则循环调用本函数

if(!Directory.Exists(path))

{

//判断是否web service的代码文件

if(path.Substring(path.Length - 8,8) == ".asmx.cs")

{

//将代码文件读入szSourceCode中

streamReader = new StreamReader(path, System.Text.Encoding.GetEncoding("GB2312"));

szSourceCode = streamReader.ReadToEnd();

streamReader.Close();

//判断是否包含m_szTagString;即判断是否已经被植入过代码

if(szSourceCode.IndexOf(m_szTagString) != -1)

{

//如果已经被植入过代码。则替换TemplateTag

//替换Try;替换Catch

szSourceCode = szSourceCode.Replace(m_szTagString, string.Empty);

szSourceCode = szSourceCode.Replace(m_szOldTryString, m_szTryString);

szSourceCode = szSourceCode.Replace(m_szOldCatchString, m_szCatchString);

}

else

{

//循环查找WebServic中的方法;(已知道规则是所有WebService方法以"[WebMethod("开头)

int nWebMethod = szSourceCode.IndexOf("[WebMethod(");

int nWebMethodEnd = -1;

while (nWebMethod != -1)

{

//调用方法得出对[WebMethod(下面第一个"{"对应的"}"的位置

nWebMethodEnd = GetWebMethodEnd(nWebMethod, szSourceCode);

//也就是将整个的Web Service的方法字符串取出存入szTemp

szTemp = szSourceCode.Substring(nWebMethod, nWebMethodEnd - nWebMethod + 1);

//备份szTemp,为下面的替换进行准备

szTemp1 = szTemp;

nStart = szTemp1.IndexOf("{");

//第一个"{"号之后加入try的字符串

szTemp1 = szTemp1.Insert(nStart + 1, m_szTryString);

//与第一个"{"对应的"}"之前加入catch的字符串

szTemp1 = szTemp1.Insert(szTemp1.Length -1 , m_szCatchString);

//将备份的szTemp进行替换

szSourceCode = szSourceCode.Replace(szTemp,szTemp1);

nWebMethod = szSourceCode.IndexOf("[WebMethod(", nWebMethod + 1);

}

}

//将文件重新写入

sb = new FileStream(path, FileMode.Create);

streamWriter = new StreamWriter (sb, System.Text.Encoding.GetEncoding("GB2312"));

//在文件字符串的开头加入TemplateTag,即打上标识,为下一次更新做准备

streamWriter.Write(m_szTagString + szSourceCode);

streamWriter.Close();

}

}

else

{

//如果是目录,递归调用本函数

GerentorCode(path);

}

}

}

Ø 代码更新的输出

代码更新的输出没有什么特殊的,只是使用新的文件内容字符串生成一个文件将以前的文件进行覆盖。

l 需要注意的部分

更新C#可以使用的代码出现的了一些问题。这里写出来,以免以后的朋友也走同样的弯路。这些问题的出现主要是与IDE环境有关系。Visual Studio.net的环境会自己对加入的代码进行一些自动的处理,这些处理将会导致最后代码更新不成功。下面是遇见的问题与解决方案:

Ø IDE的问题:

8.问题描述

生成的代码在从IDE打开之后,或者是重新进行编译之后。代码更新工具对代码文件的更新失效。

9.出现原因分析

IDE自动对代码进行了格式的整理。被替换的代码的格式已经被修改。

例如,以下的代码被注入函数之内:

<TAB><TAB>//**以下的代码为生成的代码,请不要进行修改**//

其中<TAB>是不可见的,只是表示为代码不同行之间的对齐的关系。

但此文件被IDE打开或或被编译之后,代码可能会被IDE修改,形成以下情况:

<TAB><TAB><TAB>//**以下的代码为生成的代码,请不要进行修改**//

由于我们的机制是要求找出可以与Old Source 中内容完全等同的部分以进行代码的更新,所以一定会更新失败。

² 解决方案

解决方案可以有很多种,这里我只提供出我的一种方案。我的解决方案很简单,将IDE中已经被修改的部分拷贝出来,放入Old Source 节中。这样的话,替换时就不会出现失败的情况。

例如,在上例中,我将带三个<TAB>的代码从IDE中拷贝出来,替换模板文件中的Old Source节。从而在代码更新的过程中,代码的更新就可以成功。

当然还可以有别的方法,比如可以将<TAB>忽略以进行代码更新;或者直接找出一个方法用已经生成代码文件来更新与同步模板文件。或者在模板文件中定义出两个或两个以上的oldsource节对应一个newsource节,等等。方法有很多,这里就不一一说明了。

这里要重新来强调代码生成工具与代码更新工具制作的目的了。制作代码生成工具或代码更新工具的目的实际上非常的单纯:通过各种的手段来提高开发过程的工作效率。最粗糙的代码生成工具只可以帮助提高一点点开发效率,较为细致与全面的代码生成工具可能可以从很深的层次上提升开发过程的效率。但是,这些暂时都只是工具。没有与整个的开发人员,开发工具,以及我们所开发的项目进行更深程度的结合,从而形成出一整套完整的开发流程,才有可能真正的去提升开发工作的生产率。

下周又应该到写项目总结的时候,这一个阶段遇见的问题比以前加起来遇见的问题还要多,很多朋友们以前警告过我的问题都出现了,我想具体的说一些,并对出现的问题进行一些分析。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有