如果服务以其他用户身份运行,则CompileAssemblyFromSource会引发异常

时间:2018-12-06 16:02:22

标签: c# .net windows service .net-assembly

有一个应用程序可以从源(在内存中)编译程序集,但是现在我需要在AD用户下将其作为服务运行。但这以例外结尾,我无法解决。

用例:

  1. 在我的用户下运行此应用->一切正常
  2. 在其他用户下运行此应用->异常
    C:\Windows\TEMP\deij1sv4.0.cs找不到文件(此可以通过更改TEMP的EnvironmentVariable进行修复
  3. 在其他用户和服务下运行此应用->异常
    更改TEMP的EnvironmentVariable不能修复此

代码

完整示例:https://gist.github.com/dhcgn/13529f7f37174365fd96f8fcfb9a4eb4

static void Main(string[] args)
{
    var asm = CreateInMemoryAssembly();
    dynamic foo = asm.CreateInstance("Foo");
    Console.WriteLine(foo.Bar);
    Console.ReadKey();
}

private static Assembly CreateInMemoryAssembly()
{
    var code = "using System; public class Foo { public string Bar { get { return \"Hello!\"; } } }";

    var options = new CompilerParameters
    {
        CompilerOptions = "/t:library",
        GenerateInMemory = true,
        GenerateExecutable = false,
        IncludeDebugInformation = false,
        OutputAssembly = "TestAssembly.dll",
    };
    options.ReferencedAssemblies.Add("System.dll");

    var provider = new CSharpCodeProvider();
    CompilerResults result = provider.CompileAssemblyFromSource(options, code);

    if (result.Errors.Count > 0)
    {
        var msg = result.Errors.Cast<CompilerError>().Aggregate(String.Empty, (current, error) => current + (error.ToString() + Environment.NewLine));
        throw new Exception(msg);
    }

    return result.CompiledAssembly;
}

异常

System.Exception: error CS2001: Die Quelldatei 'C:\Windows\TEMP\sesajnzr.0.cs' konnte nicht gefunden werden.
warning CS2008: Es wurden keine Quelldateien angegeben.

   bei TestConsole.Program.CreateInMemoryAssembly() in Program.cs:Zeile 51.
   bei TestConsole.Program.Main(String[] args) in Program.cs:Zeile 19.

使用TempFiles

感谢@stuartd的评论,尝试设置属性CompilerParameters.TempFiles。如果您在CoreFx上查看TempFileCollection.cs的代码,那似乎是正确的选择。

var tempDir = $@"C:\Temp\Temp_{Guid.NewGuid()}\";
Directory.CreateDirectory(tempDir);
var tempFileCollection = new TempFileCollection(tempDir,true);
tempFileCollection.AddExtension("cs");

var options = new CompilerParameters
{
    CompilerOptions = "/t:library",
    GenerateInMemory = true,
    GenerateExecutable = false,
    IncludeDebugInformation = false,
    OutputAssembly = "TestAssembly.dll",
    TempFiles = tempFileCollection
};

与当前用户一起使用

enter image description here

不能与runas用户一起使用

System.Exception: error CS1567: Fehler beim Generieren der Win32-Ressource: Zugriff verweigert
warning CS1610: Die temporäre Datei 'c:\Windows\System32\CSCEDE8DE40DD0A4ABBB937
A76D35F24C15.TMP', die für die Win32-Standardressource verwendet wird, kann nich
t gelöscht werden -- Das System kann die angegebene Datei nicht finden.

   bei TestConsole.Program.CreateInMemoryAssembly() in Program.cs:Zeile 58.
   bei TestConsole.Program.Main(String[] args) in Program.cs:Zeile 20.

0 个答案:

没有答案