1.问题: 最近设计的一个新的搜索系统,在POC阶段,用codedom编译动态搜索代码遇到了一个问题,
progams={a.cs,b.cs,.....,z.cs},
是放在某一文件夹下面的搜索代码,这些代码要用到的部件
dlls ={1.dll,2.dll,....,n.dll},
每个搜索的client 有多个项目
projs ={p1,p2,....pk},
其中p1是startup proj,p2配了dlls,负责向service索要新的搜索代码 x.cs,再使用codedom编译,运行搜索,第一遍运行出现问题的代码是
CompilerResults result = CodeDomHelper.Compily(null ,source ,CodeDomHelper.defaultNamespace ,CodeDomHelper .GetDefaultFolder() );
CodeDomHelper 相关的代码如下,
public static CompilerResults Compily(string compilerVersion, string code, string[] importNamespaces )
{
CompilerResults result = null;
CSharpCodeProvider csp = GetCsp(compilerVersion);
CompilerParameters opt = GetOpt(importNamespaces);
result = csp.CompileAssemblyFromSource(opt, code);
return result;
}
static CSharpCodeProvider GetCsp(string compilerVersion)
{
Dictionary<string, string> providerOptions = new Dictionary<string, string>();
string version = string.IsNullOrEmpty(null) ? "v3.5" : compilerVersion;
providerOptions.Add("CompilerVersion", version);
return new CSharpCodeProvider(providerOptions);
}
static CompilerParameters GetOpt(string[] importNamespaces)
{
CompilerParameters opt = new CompilerParameters();
opt.GenerateExecutable = false;
opt.TreatWarningsAsErrors = false;
opt.IncludeDebugInformation = true;
opt.GenerateInMemory = true;
if (importNamespaces != null && importNamespaces.Length > 0)
foreach (string ns in importNamespaces)
opt.ReferencedAssemblies.Add(ns);
return opt;
}
在测试的时候发现,result .Errors .HasErrors =true ,打开错误list, 都是找不到 dlls里面的 dll.
2.原因:dlls是存放在p2对应的debug文件夹p2.debug下面。系统在编译时是自动在
string folder =Directory.GetCurrentDirectory()
文件夹下加载dlls, 当 p2.debug != folder时 ,系统就找不到dlls 中的dll。
3.解决办法:把当前工作文件夹设置为p.debug ,
Directory.SetCurrentDirectory(p.debug );
最终CodeDomHelper相关的代码如下:
public static CompilerResults Compily(string compilerVersion, string code, string[] importNamespaces, string fromFolder)
{
string folder = Directory.GetCurrentDirectory();
CompilerResults result = null;
if (Directory .Exists(fromFolder ))
{
Directory.SetCurrentDirectory(fromFolder);
CSharpCodeProvider csp = GetCsp(compilerVersion);
CompilerParameters opt = GetOpt(importNamespaces);
result = csp.CompileAssemblyFromSource(opt, code);
Directory.SetCurrentDirectory(folder);
}
return result;
}
static CSharpCodeProvider GetCsp(string compilerVersion)
{
Dictionary<string, string> providerOptions = new Dictionary<string, string>();
string version = string.IsNullOrEmpty(null) ? "v3.5" : compilerVersion;
providerOptions.Add("CompilerVersion", version);
return new CSharpCodeProvider(providerOptions);
}
static CompilerParameters GetOpt(string[] importNamespaces)
{
CompilerParameters opt = new CompilerParameters();
opt.GenerateExecutable = false;
opt.TreatWarningsAsErrors = false;
opt.IncludeDebugInformation = true;
opt.GenerateInMemory = true;
if (importNamespaces != null && importNamespaces.Length > 0)
foreach (string ns in importNamespaces)
opt.ReferencedAssemblies.Add(ns);
return opt;
}
nothing is impossible