首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从WCF应用程序调用CompileAssemblyFromSource时发出问题

从WCF应用程序调用CompileAssemblyFromSource时发出问题
EN

Stack Overflow用户
提问于 2012-04-04 09:56:34
回答 2查看 1.1K关注 0票数 0

我有一个WCF服务,它公开一个方法。当客户端调用此方法时,会发生以下情况:

  1. 方法做了一些处理,它尝试加载一个程序集,如果它已经存在,如果上面的dll不存在,它生成C#代码,使用CSharpCodeProvider的CompileAssemblyFromSource api
  2. 编译它,然后加载刚刚生成的程序集

< code >G29

现在问题来了。第一次调用该方法时,它在第3点生成程序集,当它试图通过CompilerResults.CompiledAssembly返回程序集引用时,它将抛出一个未找到的异常文件。但是,我可以清楚地看到,程序集是在指定的位置生成的,我可以使用其他应用程序打开它。

如果我再次通过客户端调用该方法,它就能够加载程序集(由于上一次调用而成功生成),然后继续执行其余的一组任务。只有当程序集不存在并且生成它并立即加载它时,我才会得到这个异常。有什么想法吗?我试着玩web.config,把模拟变成真/假。我有一个独立的应用程序池来运行这个web应用程序,我尝试将应用程序池的身份从本地服务更改为本地系统,甚至给了我的windows登录凭据,它有管理权限,但没有运气。

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-24 11:05:06

谢谢user1796307的投入。我已经解决了这个问题,但忘了更新。为了每个人的利益而分享。这是.NET聚变的作用。它缓存程序集加载路径,如果以前尝试从同一位置加载程序集失败,甚至不会尝试加载程序集。换言之:

代码语言:javascript
复制
if (Assembly.Load("C:\xyz.dll") == null)
 {
    Compile("C:\xyz.dll"); // Now the dll exists
    Assembly.Load("C:\xyz.dll"); // this will still fail
 }


The solution is to change it as:

    if (!File.Exists("C:\xyz.dll")
{
  Compile("C:\xyz.dll"); // Now the dll exists
  Assembly.Load("C:\xyz.dll"); // this will now work

}
票数 0
EN

Stack Overflow用户

发布于 2013-01-30 15:10:47

你确定它在生成程序集吗?我也有同样的问题,只是找不到生成的.dll。我最初怀疑它无法写入文件夹,因此它现在调用CreateDirectory并删除一个文本文件,以证明该文件夹是可写的。

总之,同样的问题,没有成功。是否真的没有其他人有这个问题?

我要对服务器进行远程调试&看看是否可以通过Microsoft的PDB.

-编辑--

不需要一步一步地了解微软的代码。我查看了CompilerResults的错误集合,其中有一项:“元数据文件'c:\Windows\System32\aaclient.dll‘无法打开--’尝试加载格式不正确的程序‘。”

当我得到Directory.GetCurrentDirectory()来获取其他DLL时,它将指定System32目录.

-编辑--

通过从正在执行的程序集的文件夹中添加引用来解决此问题:

代码语言:javascript
复制
CompilerParameters compilerParameters = new CompilerParameters
    {
        OutputAssembly = Path.Combine(GeneratedAssembliesFolder, string.Format("{0}.Generated.dll", typeName))
    };
string executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string[] dllFiles = Directory.GetFiles(executingDirectory, "*.dll");
compilerParameters.ReferencedAssemblies.AddRange(dllFiles.Select(f => Path.Combine(executingDirectory, f)).ToArray());
IEnumerable<string> exeFiles =Directory.GetFiles(executingDirectory, "*.exe").Where(f => !f.Contains(".vshost."));
compilerParameters.ReferencedAssemblies.AddRange(exeFiles.Select(f => Path.Combine(executingDirectory, f)).ToArray());

为了获得更强的健壮性,可以添加对二进制文件是否有效的托管代码程序集的检查。这段代码也可以通过在两个.Union调用之间使用Linq .Union来缩短。

若要找到要写入的适当文件夹,请执行以下操作:

代码语言:javascript
复制
private static string generatedAssembliesFolder;

private static string GeneratedAssembliesFolder
{
    get
    {
        if (generatedAssembliesFolder == null)
        {
            string[] candidateFolders = new[]
                {
                    Environment.GetEnvironmentVariable("TEMP", EnvironmentVariableTarget.Process),
                    Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.Process),
                    Environment.GetEnvironmentVariable("TEMP", EnvironmentVariableTarget.User),
                    Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.User),
                    Environment.GetEnvironmentVariable("TEMP", EnvironmentVariableTarget.Machine),
                    Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.Machine),
                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                    Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
                };
            foreach (string candidateFolder in candidateFolders)
            {
                try
                {
                    if (!Directory.Exists(candidateFolder)) Directory.CreateDirectory(candidateFolder);
                    string testFileName = Path.Combine(candidateFolder, Path.GetRandomFileName());
                    File.WriteAllBytes(testFileName, new byte[0]);
                    File.Delete(testFileName);
                }
                catch (Exception ex)
                {
                    continue;
                }
                generatedAssembliesFolder = candidateFolder;

                break;
            }
        }
        return generatedAssembliesFolder;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10008841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档