Net有道

紫冠道人的求道历程

导航

<2004年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

与我联系

搜索

 

常用链接

留言簿(21)

我参与的团队

随笔分类

随笔档案

文章分类

文章档案

Program

程序之外的生活

我的阅读BLOG

积分与排名

最新评论

  • 1. re: 动态生成与编译(九)----CodeDOM的局限
  • @vivisimo
    没有这种功能,反正以前微软只提供了一个没有任何实现的空的接口在那。
    不知新版本后有什么改进。
  • --lichdr
  • 2. re: 动态生成与编译(九)----CodeDOM的局限
  • 请问要编一个对C#语法程序的词法分析器,codeDom中有没有什么方法和类封装了这样的功能,可以被直接使用的?或者C#中有没有其他这样的类或方法?词法分析程序中要提取程序的单词,并对单词的种类进行识别...
  • --vivisimo

阅读排行榜

评论排行榜

CodeDOM浅析(下)

 

生成以后是编译了。在生成的时候,从GenerateCodeFromCompileUnit()这个方法开始,ICodeGenerator里面的其他几个方法都可以被调用到;而在ICodeCompiler里,接口里的方法最后都会调用到这么一个FromFileBatch()方法里来。那么看看在CodeCompiler这个类里是如何实现这个方法的:

 

protected virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames){
      …….
//前面一些处理略
      string text3 = this.CmdArgsFromParameters(options) + " " + CodeCompiler.JoinStringArray(fileNames, " ");
      
string text4 = this.GetResponseFileCmdArgs(options, text3);
      
string text5 = null;
      
if (text4 != null)      {
            text5 
= text3;
            text3 
= text4;
      }

      
this.Compile(options, Executor.GetRuntimeInstallDirectory(), this.CompilerName, text3, ref text1, ref num1, text5);
      ……
//下面为编译结果的处理,略
}

 

问题在this.Compile()这里了,再寻根问底下去:

 

internal void Compile(CompilerParameters options, string compilerDirectory, string compilerExe, string arguments, ref string outputFile, ref int nativeReturnValue, string trueArgs){
     ……
      
string text2 = compilerDirectory + compilerExe;
     ……
      nativeReturnValue 
= Executor.ExecWaitWithCapture(options.UserToken, "\"" + text2 + "\" " + arguments, options.TempFiles, ref outputFile, ref text1, text3);
     ……
}

 

出来一个新东西Executor,执行者?就是这个东西,调用命令行编译就是它来做的,而CodeCompiler只是提供出一个命令行字符串而已。ExecutorSystem.CodeDom.Compiler里公开的sealed类,里面全是一些静态方法,追呀追呀追,最后到了这里:

 

private static int ExecWaitWithCaptureUnimpersonated(IntPtr userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine){
       …….
       flag1 
= UnsafeNativeMethods.CreateProcess(nullnew StringBuilder(cmd), nullnulltrue0new HandleRef(null, ptr4), currentDir, startupinfo1, process_information1);
       …….
       
int num2 = SafeNativeMethods.WaitForSingleObject(new HandleRef(null, process_information1.hProcess), 600000);
       …….
       
if (!UnsafeNativeMethods.GetExitCodeProcess(new HandleRef(null, process_information1.hProcess), ref num3))       {
          ……        
         }

        
return num3;
      …….
 }

 

好熟悉的东西呀,什么CreateProcessWaitForSingleObject。跑到SafeNativeMethods(UnsafeNativeMethods)那边一瞧,不得了,熟悉的面孔一大堆,好多的[DllImport()]。原来在.NET下调用命令行没什么新着呀。

 

上面的东西跟好象跟Provider一点关系都没有。不过也不对呀,编译的时候它是如何找到编译器的呢?Provider肯定在这里起作用的喽。就是this.Compile()那个方法的第三个参数:this.CompilerName,这是一个抽象的属性,具体的值在相关的Provider里提供。注意一下CSharpCodeGenerator这个类,它是从CodeCompiler继承的。这里有个比较有趣的继承关系:

public abstract class CodeGenerator : ICodeGenerator
public abstract class CodeCompiler : CodeGenerator, ICodeCompiler
internal class CSharpCodeGenerator : CodeCompiler

倒不是继承关系有趣,而是名字取得比较的趣,CSharpCodeGenerator这个类原来把生成与编译功能的都包括在里面了,上面那个CompilerName的属性值就是在CSharpCodeGenerator里提供的,好象有点乱(看来看去总觉得当初CodeCompilerCodeGenerator继承是为了后面CSharpCodeGenerator准备的﹐在CodeCompiler里根本是没改写过CodeGenerator什幺东西﹐一股脑就丢给CSharpCodeGenerator)。刚开始没注意到这个继承关系,而且也没注意到CSharpCodeGenerator里有CompilerName这样的属性值(藏得太下面了,要点两下滚动条才出来),对它的值是如何得到的百思不得其解。

    编译的事也搞定。

 

System.CodeDom.Compiler里三大接口去其二,还有一个ICodeParser没人管,MS自己也没有提供相应的实现的,在网上倒是有看到过一个。很吓人的东西,复杂的字符串分析,整段整段的switch。描了两眼,还是没有跳进去。

 

CodeDOM分析就此结束,看下来一点奥秘都没有,否则也不叫浅析了。其实奥秘都在省略的那些东西里,那些才是见真功夫的。

posted on 2004-11-29 11:44 lichdr 阅读(2673) 评论(11)  编辑 收藏 所属分类: CodeDOM

评论

#1楼  2004-11-29 11:50 dudu      

请调整一下排版再发布。   回复  引用  查看    

#2楼  2004-11-29 12:01 dudu      

文章中含有WIDTH: 100%,影响了首页的显示。请修改一下, 再发布。   回复  引用  查看    

#3楼 [楼主] 2004-11-29 13:07 lichdr      

這下好了.

代碼是從Reflector拷的到WORD里的(那里出來個表格)﹐從WORD里到這兒就亂掉了。把里面的表格刪掉就好了。   回复  引用  查看    

#4楼  2005-09-14 16:53 ventman [未注册用户]

楼主,我看了几天的CodeDom,还是搞不太明白CodeDom是做什么用的。
看起来似乎是用来动态生成.cs文件的。
我现在在做一个例子,内容很简单,就是动态生成控件,但是动态生成控件的事件希望也能够动态生成,并且在当前页面可用,可以用CodeDom吗?还是可以有其它的方法,如果楼主知道,能不能告诉我?谢谢   回复  引用    

#5楼 [楼主] 2005-09-15 16:04 lichdr      

CODEDOM是干什么用的,MSDN上就有的啦.
装个.NET SDK,就可以.

动态生成CS文件只是一个小小的方面,它的作用比之要强大得多,如果只是动态生成CS代码用不着这个东西的.

至于你说的动态生成控件,事件.不是很清楚你的场景.不会是要动态的写个自定义控件吧.

应该就是在画面上动态的画一些框框(控件类已经有了),框框上有一些事件之类的(动态生成菜单?),这个用不着什么CODEDOM.   回复  引用  查看    

#6楼  2006-04-13 11:11 tianyamoon [未注册用户]

请教个问题.net在拖放控件出来的时候会自动生成些代码。这些代码是怎么生成出来的啊?我目前用CodeDom类已经能够生成代码了,但是我想把这个功能做到控件里,比如在拖一个UserControl出来的时候,在源代码里加入自己定义好的一些代码或者运算。   回复  引用    

#7楼 [楼主] 2006-04-21 11:33 lichdr      

IDE的代码生成是用模板的。
。。\Microsoft Visual Studio .NET 2003\VC#\VC#Wizards目录下有一堆模板可以看看。   回复  引用  查看    

#8楼  2006-08-06 14:23 main      

comdedom全部完了,老大能不能介绍介绍这玩意到底哪些地方需要呢?   回复  引用  查看    

#9楼  2007-08-06 19:18 Gavin [未注册用户]

谁来告诉我 生成出来的头注释如何去掉?
或是COMDOM类提供有相关属性可以控制!
QQ:240101561   回复  引用    

#10楼 [楼主] 2007-08-07 10:05 lichdr      

@Gavin
在.net 1.1时时是没有控制的,在.net2.0有没有我不太清楚,自己可以去查一下。

一般来说那个东西放那也没什么不好的,我不但不去掉,而且还要加上一大段呢。   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-11-29 13:00 编辑过