C# 在Azure上使用Codedom/CSharpCodeProvider进行动态编译
我正在使用以下代码动态编译一些代码,并将生成的DLL存储在Azure存储中 当我在本地运行它时,一切正常,但当使用Azure部署版本时,一切都不正常 我现在已经尝试了很多东西 这是我正在使用的最新版本。这不会引发任何错误,但不会存储DLL(存储方法工作正常,因为它在许多其他地方使用)。我假设权限有问题,或者DLL没有存储为文件C# 在Azure上使用Codedom/CSharpCodeProvider进行动态编译,c#,.net,azure,codedom,C#,.net,Azure,Codedom,我正在使用以下代码动态编译一些代码,并将生成的DLL存储在Azure存储中 当我在本地运行它时,一切正常,但当使用Azure部署版本时,一切都不正常 我现在已经尝试了很多东西 这是我正在使用的最新版本。这不会引发任何错误,但不会存储DLL(存储方法工作正常,因为它在许多其他地方使用)。我假设权限有问题,或者DLL没有存储为文件 public Tuple<bool,string> compileAndStoreCodeAsDLL(Guid actionID, string action
public Tuple<bool,string> compileAndStoreCodeAsDLL(Guid actionID, string actionName, string actionMethod, string code)
{
string newFileName = "AncillaryTestMethods_" + actionName + ".dll";
try
{
// Compile the code
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.OutputAssembly = newFileName;
parameters.GenerateInMemory = false;
parameters.TempFiles = new TempFileCollection(".", true);
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, code);
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, results.CompiledAssembly);
// Store the code in the current firm's azure directory/ActionDLLs
this.putFile(stream, newFileName, "ActionDLLs");
// Return ok
return new Tuple<bool, string>(true, null);
}
catch (Exception e)
{
// Return fail
return new Tuple<bool, string>(true, e.Message);
}
}
public Tuple compileAndStoreCodeAsDLL(Guid actionID、字符串actionName、字符串actionMethod、字符串代码)
{
字符串newFileName=“辅助测试方法”+actionName+“.dll”;
尝试
{
//编译代码
CSharpCodeProvider codeProvider=新的CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters参数=新的CompilerParameters();
parameters.GenerateExecutable=false;
parameters.outputasembly=newFileName;
parameters.GenerateInMemory=false;
parameters.TempFiles=newtempfilecollection(“.”,true);
parameters.referencedAssembly.Add(“System.dll”);
parameters.referencedAssembly.Add(“System.Core.dll”);
parameters.referencedAssembly.Add(“Microsoft.CSharp.dll”);
CompilerResults results=codeProvider.CompileAsemblyFromSource(参数,代码);
MemoryStream stream=新的MemoryStream();
BinaryFormatter formatter=新的BinaryFormatter();
序列化(流、结果、编译汇编);
//将代码存储在当前公司的azure目录/ActionDLL中
这个.putFile(流,newFileName,“actiondll”);
//返回ok
返回新元组(true,null);
}
捕获(例外e)
{
//返回失败
返回新元组(true,例如Message);
}
}
我从这段代码开始(这段代码在本地也有效):
public Tuple compileAndStoreCodeAsDLL(Guid actionID、字符串actionName、字符串actionMethod、字符串代码)
{
字符串newFileName=“辅助测试方法”+actionName+“.dll”;
尝试
{
//编译代码
CSharpCodeProvider codeProvider=新的CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters参数=新的CompilerParameters();
parameters.GenerateExecutable=false;
parameters.outputasembly=newFileName;
parameters.referencedAssembly.Add(“System.dll”);
parameters.referencedAssembly.Add(“System.Core.dll”);
parameters.referencedAssembly.Add(“Microsoft.CSharp.dll”);
CompilerResults results=codeProvider.CompileAsemblyFromSource(参数,代码);
//将代码存储在当前公司的azure目录/ActionDLL中
这个.putFile(results.compiledsassembly.GetFile(newFileName)、newFileName、“actiondll”);
//返回ok
返回新元组(true,null);
}
捕获(例外e)
{
//返回失败
返回新元组(true,例如Message);
}
}
但在Azure上引发了一个错误“生成Win32资源时出错:访问被拒绝。无法删除用于默认Win32资源的临时文件“d:windows\system32\inetsrv…tmp”-系统找不到指定的文件
这可能与Azure权限有关,因此我尝试了上面的代码
有人能建议对Azure中的函数进行任何修改吗?经过17个小时的研究,我终于让它工作起来了。情况非常糟糕,我甚至尝试连接FluidSharp库中的Roslyn类,但它们自己也有一些重大问题 这里有三个核心问题:
希望这能为其他人省去一大堆麻烦!请注意,我刚刚意识到捕获异常时出现了一个错误,因为我要返回false,而不是true。我将在修复此问题后进行更新。在更正异常块以返回false后,该方法现在正确地报告另一个错误“对路径“d:\windows\system32\inetsrv\..tmp”的访问被拒绝。因此,另一个Azure许可问题。是否可以将临时文件写入我有权限访问的位置?我现在更改了tempfiles的位置,以便该行显示“parameters.tempfiles=new TempFileCollection(System.IO.Path.GetTempPath(),false);”。然而,这没有什么区别。。。仍然拒绝访问。哪一行实际抛出该异常?是否从源代码或行编译SemblyFromSource以将文件保存到本地目录?此代码是部署到网站、Web角色、工作者角色还是虚拟机?@Simon,引发异常的行是CompilerResults results=codeProvider.CompileAsemblyFromSource(参数、代码);现在我几乎可以肯定,这是由于内部没有正确使用CodeDom参数造成的。在Azure上,即使我将其设置为t,也始终存在拒绝访问的消息
public Tuple<bool,string> compileAndStoreCodeAsDLL(Guid actionID, string actionName, string actionMethod, string code)
{
string newFileName = "AncillaryTestMethods_" + actionName + ".dll";
try
{
// Compile the code
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.OutputAssembly = newFileName;
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, code);
// Store the code in the current firm's azure directory/ActionDLLs
this.putFile(results.CompiledAssembly.GetFile(newFileName), newFileName, "ActionDLLs");
// Return ok
return new Tuple<bool, string>(true, null);
}
catch (Exception e)
{
// Return fail
return new Tuple<bool, string>(true, e.Message);
}
}