最近,完成的工作中,需要使用CodeSmith生成代码。
我的思路是这样的:
1. 用户的参数,写入在CSP文件中。
2. 括展了CSP文件,因为这个文件是CodeSmith的项目文件,里面存着生成代码时的所有信息。而且是XML格式的,所以,可以对之进行扩展。
3. 然后,调用CodeSmith API,通过CSP来生成目标代码。我现在的的目标代码,是一个perl脚本程序的变量部分。
然而,在部署时,遇到一系列困难。
首先,因为我的Codesmith并不是正版的,所以在网上找了Codesmith.Engine的动态库。
而工作环境,需要绿色化。我一直没找到门道,一开始是装好CodeSmith后,然后把Crack的dll拷到这:C:\WINDOWS\assembly\GAC_MSIL\CodeSmith.Engine\5.0.0.0__9fd61cdb91609a7a
,over wirte 原有的。然后把这个目录只读。因为Codesmith启动时会检查。
这样,也实出了,程序和软件都可以使用。
但这种方式,经过反复尝试,证实,几乎无法部署到别的机器上去。
所以,我想到了彻底绿色化。
以过一番功夫,的确做到了。现在,我的CodeSmith在没有安装的机器上,也可以启动。
然而,新的问题出现了:如果目录更换,代码无法生成。
这里到了本文的重点。
========================================================================
1. 我的程序的代码如下:
ProjectCodeGenerator myGen = new ProjectCodeGenerator();
return myGen.GenerateCode(cspPath);
如果目录变更后,这段代码将无法执行。
2. 但我发现,手工启动CodeSmith后,并且在这个对话框里点是,就可以正确生成了:
3. 所以,我分析了注册表。
发现这里有不同:
已改变值 (10) 快照 A |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Map\DefaultIcon] |
@="E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmithResources.dll,8" |
@="E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmithResources.dll,8" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Map\Shell\edit\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmith.exe\" /edit \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmith.exe\" /edit \"%1\"" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Project\DefaultIcon] |
@="E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmithResources.dll,7" |
@="E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmithResources.dll,7" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Project\Shell\add\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmith.exe\" /add \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmith.exe\" /add \"%1\"" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Project\Shell\generate\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmith.exe\" /generate \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmith.exe\" /generate \"%1\"" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Project\Shell\manage\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmith.exe\" /manage \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmith.exe\" /manage \"%1\"" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Template\DefaultIcon] |
@="E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmithResources.dll,2" |
@="E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmithResources.dll,2" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Template\Shell\edit\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmithStudio.exe\" \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmithStudio.exe\" \"%1\"" |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CodeSmith.Template\Shell\execute\command] |
@="\"E:\\work2\\AutoPack\\07_MyParser_New\\out\\debug\\bin\\CodeSmith.exe\" \"%1\"" |
@="\"E:\\work2\\AutoPack\\07_MyParser\\out\\debug\\bin\\CodeSmith.exe\" \"%1\"" |
4. 这里我面临选择:是自己写代码来搞定注册表的关联信息的注入,还是利用CodeSmith的本身的功能来解决。
当然,Codesmith是首选,但他的手册里,很可能没用。
怎么办?
5. 用ILSpy_Debugger打开程序CodeSmthStudio
6. 在代码中搜索:
竟然找到了:
7. 剩下的就好办了:
改成这样就可以了:
if (!FileAssociationManager.IsAssociated)
{
FileAssociationManager.AddFileAssociation();
}
ProjectCodeGenerator myGen = new ProjectCodeGenerator();
return myGen.GenerateCode(cspPath);
~~~~~~~~~~~~~~~~~~~~~~~~~~~