2012-04-04 11 views
0

メソッドを公開するWCFサービスがあります。クライアントがこのメソッドを呼び出すと、次のことが起こる:WCFアプリケーションから呼び出されたときのCompileAssemblyFromSourceの問題

  1. 方法は、いくつかの処理
  2. を行い、それはアセンブリをロードしようとすると、その既にある
  3. 上記のdllがない場合、それは、C#を生成し、コードは、それはそれからちょうど生成されたアセンブリ

問題をロードCSharpCodeProviderのCompileAssemblyFromSourceのAPI

  • を使用して、それをコンパイルします。メソッドを初めて呼び出すと、ポイント3でアセンブリが生成されます)、CompilerResults.CompiledAssemblyを介してアセンブリ参照を返そうとすると、ファイルが見つからない例外がスローされます。しかし、アセンブリが指定された場所に生成されていることがわかり、他のアプリケーションでもアセンブリを開くことができます。

    クライアントからメソッドをもう一度呼び出すと、アセンブリをロードすることができます(以前の呼び出しの結果として正常に生成されました)。残りの一連のタスクを実行します。アセンブリがそこにないときにのみそれを生成し、すぐにロードするために先に進むと、私はその例外を取得します。何か案は?私は偽装をtrue/falseに変更してweb.configを試してみました。私はこのWebアプリケーションを実行するための別個のアプリケーションプールを持っており、ローカルプールからローカルシステムにアプリケーションプールのIDを変更しようとしました。

    ご協力いただければ幸いです。

  • 答えて

    0

    おかげで、あなたの入力のためのuser1796307:

    はへの書き込みに適当なフォルダを検索します。私はこの問題を解決しましたが、更新するのを忘れました。みんなの利益のためにそれを共有する。それは、プレー中の.NET Fusionでした。これは、アセンブリのロードパスをキャッシュし、以前の同じ場所からのロードが失敗した場合でもアセンブリをロードしようとしません。言い換えれば、

    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 
    
    } 
    
    1

    アセンブリを生成していますか?私は生成された.dllを見つけることができないことを除いて、同じ問題を抱えています。最初にフォルダに書き込めないと思われたので、今度はCreateDirectoryを呼び出し、フォルダが書き込み可能であることを示すテキストファイルをドロップします。

    とにかく、同じ問題、成功しません。誰もこの問題を抱えていないのは本当ですか?私はMicrosoftののPDBをステップ実行することができた場合、サーバー&が見リモートデバッグに行くよ

    ...

    - EDIT -

    Microsoftのコードをステップ実行する必要はありません。私はCompilerResultsのErrorsコレクションを見て、そこに1つのアイテムがあります: "メタデータファイル 'c:\ Windows \ System32 \ aaclient.dll'を開くことができませんでした - '間違ったフォーマット「」

    私は...それはWindowsのSystem32ディレクトリをusignだ他のDLLをピックアップしDirectory.GetCurrentDirectoryを()を取得すると

    - 。

    を追加することでこれを解決 - EDIT実行アセンブリのフォルダからの参照:

    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()); 
    

    堅牢性を高めるには、有効なマネージコードアセンブリであるバイナリのチェックを追加する必要があります。このコードでも、2つのGetFiles呼び出しの間にLinq.Unionを使用して短縮することができます。

    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; 
        } 
    } 
    
    関連する問題