Pregunta

I have used a ReportViewer control in my Winforms application. The reports contain some expressions, so it tries to create "expression host" assemblies in temp folder. Unless I run the program with administrator privilege (i.e. right-click, select 'run as admin...'), I get this error message:

"Access to the path 'C:\Users\user\AppData\Local\Temp\expression_host_351sf52dsf5.dll' is denied"

Now the real problem is that on my customer's client machines, users don't have access to admin account. What should I do?

I checked and the above dll is created in temp folder, but the program can not access it. I've also given Full Control permission to Everyone in security tab of 'C:\Users\user\AppData\Local\Temp' properties window. But with no success.

I've also tried to run the following code before loading the report:

reportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(new
System.Security.PermissionSet(System.Security.Permissions.PermissionState.Unrestricted));

And this one:

reportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(AppDomain.CurrentDomain.PermissionSet.Copy());

I've spent more than a few weeks trying to solve this. It happens both on my machine as well as client oes. Any ideas are welcome.

EDIT: I noticed that Report Viewer tries to 'delete' that file, and this gives an error. Here is the stack trace:

Microsoft.Reporting.WinForms.LocalProcessingException: An error occurred during local 
report processing. ---> Microsoft.Reporting.DefinitionInvalidException: The definition of the report 'D:\Projects\MyProject\bin\Reports\Report1.rdl' is invalid. ---> Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: An unexpected error occurred in Report Processing. ---> System.UnauthorizedAccessException: Access to the path 'C:\Users\User1\AppData\Local\Temp\expression_host_2bc11a902f7142e9a62bb28fd36c2d26.dll' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.Delete(String path)
   at Microsoft.ReportingServices.RdlExpressions.ExprHostCompiler.InternalCompile(Report report, AppDomain compilationTempAppDomain, Boolean refusePermissions)
   at Microsoft.ReportingServices.RdlExpressions.ExprHostCompiler.<>c__DisplayClass1.<Compile>b__0()
   at Microsoft.ReportingServices.Diagnostics.RevertImpersonationContext.<>c__DisplayClass1.<Run>b__0(Object state)
   at System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
   at Microsoft.ReportingServices.Diagnostics.RevertImpersonationContext.Run(ContextBody callback)
   at Microsoft.ReportingServices.RdlExpressions.ExprHostCompiler.Compile(Report report, AppDomain compilationTempAppDomain, Boolean refusePermissions)
   at Microsoft.ReportingServices.ReportPublishing.ReportPublishing.Phase3(ICatalogItemContext reportContext, ParameterInfoCollection& parameters, AppDomain compilationTempAppDomain, Boolean generateExpressionHostWithRefusedPermissions, Dictionary`2& groupingExprCountAtScope)
   at Microsoft.ReportingServices.ReportPublishing.ReportPublishing.CreateIntermediateFormat(ICatalogItemContext reportContext, Byte[] definition, IChunkFactory createChunkCallback, CheckSharedDataSource checkDataSourceCallback, ResolveTemporaryDataSource resolveTemporaryDataSourceCallback, DataSourceInfoCollection originalDataSources, PublishingErrorContext errorContext, AppDomain compilationTempAppDomain, Boolean generateExpressionHostWithRefusedPermissions, IDataProtection dataProtection, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks)
   at Microsoft.ReportingServices.ReportProcessing.ReportProcessing.CompileOdpReport(ICatalogItemContext reportContext, Byte[] reportDefinition, IChunkFactory createChunkCallback, CheckSharedDataSource checkDataSourceCallback, ResolveTemporaryDataSource resolveTemporaryDataSourceCallback, DataSourceInfoCollection originalDataSources, PublishingErrorContext errorContext, AppDomain compilationTempAppDomain, Boolean generateExpressionHostWithRefusedPermissions, IDataProtection dataProtection, String& reportDescription, String& reportLanguage, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks)
   at Microsoft.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(ICatalogItemContext reportContext, Byte[] reportDefinition, IChunkFactory createChunkFactory, CheckSharedDataSource checkDataSourceCallback, ResolveTemporaryDataSource resolveTemporaryDataSourceCallback, DataSourceInfoCollection originalDataSources, AppDomain compilationTempAppDomain, Boolean generateExpressionHostWithRefusedPermissions, ReportProcessingFlags processingFlags, IDataProtection dataProtection)

File.Delete() is being called in ExprHostCompiler.InternalCompile(). A look via Reflector says that it happens this way (look at the end code block inside finally):

private byte[] InternalCompile(Report report, AppDomain compilationTempAppDomain, bool refusePermissions)
{
    if (this.m_builder.HasExpressions)
    {
        CompilerParameters options = new CompilerParameters {
            OutputAssembly = string.Format(CultureInfo.InvariantCulture, "{0}{1}.dll", new object[] { Path.GetTempPath(), report.ExprHostAssemblyName }),
            GenerateExecutable = false,
            GenerateInMemory = false,
            IncludeDebugInformation = false
        };
        options.ReferencedAssemblies.Add("System.dll");
        options.ReferencedAssemblies.Add(typeof(ReportObjectModelProxy).Assembly.Location);
        options.CompilerOptions = options.CompilerOptions + this.m_langParser.GetCompilerArguments();
        if (report.CodeModules != null)
        {
            this.ResolveAssemblylocations(report.CodeModules, options, this.m_errorContext, compilationTempAppDomain);
        }
        CompilerResults results = null;
        try
        {
            CodeCompileUnit exprHost = this.m_builder.GetExprHost(report.IntermediateFormatVersion, refusePermissions);
            report.CompiledCodeGeneratedWithRefusedPermissions = refusePermissions;
            CodeDomProvider codeCompiler = this.m_langParser.GetCodeCompiler();
            results = codeCompiler.CompileAssemblyFromDom(options, new CodeCompileUnit[] { exprHost });
            if (Global.Tracer.TraceVerbose)
            {
                try
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter(stream), "    ");
                        codeCompiler.GenerateCodeFromCompileUnit(exprHost, writer, new CodeGeneratorOptions());
                        writer.Flush();
                        stream.Position = 0L;
                        Global.Tracer.Trace(new StreamReader(stream).ReadToEnd());
                    }
                }
                catch
                {
                }
            }
            if ((results.NativeCompilerReturnValue != 0) || (results.Errors.Count > 0))
            {
                this.ParseErrors(results, report.CodeClasses);
                return new byte[0];
            }
            using (FileStream stream2 = File.OpenRead(results.PathToAssembly))
            {
                byte[] buffer = new byte[stream2.Length];
                int num = stream2.Read(buffer, 0, (int) stream2.Length);
                Global.Tracer.Assert(num == stream2.Length, "(read == fs.Length)");
                return buffer;
            }
        }
        finally
        {
            if ((results != null) && (results.PathToAssembly != null))
            {
                File.Delete(results.PathToAssembly); //<------- Here!
            }
        }
    }
    return new byte[0];
}

Is there at least a way to prevent it from deleting?

¿Fue útil?

Solución

I can't believe my problem is finally solved with just a click! Look at this blog post. I disabled my AV and voila!

Otros consejos

It looks like you're almost there, just missing one piece.

According to the documentation for LocalReport.SetBasePermissionsForSandboxAppDomain, you must add a permission for Execution: "... You should make sure that the supplied permission set includes the Execution permission. Otherwise, no custom code assemblies can be executed and no expressions can be evaluated."

Try the following sequence:

    PermissionSet permissions = new PermissionSet(PermissionState.None);
    permissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
    permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));  // The missing piece

    reportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(permissions);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top