句柄无效。(HRESULT 异常: 0x80070006 (E_HANDLE))

24

我在一个运行.NET 3.5的IIS 7共享托管环境中拥有一个网站。我有一个下载按钮,用于从服务器下载文件。

当我在本地将此应用程序部署到IIS 6时,它可以正常运行。但是在IIS 7共享托管服务器上,会发生异常。

  

The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))   Description: 在当前 Web 请求的执行过程中引发了未经处理的异常。请检查堆栈跟踪以获取有关错误的更多信息以及错误的原始位置。
  System.Runtime.InteropServices.COMException: The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))
  COMException (0x80070006): The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))] [HttpException (0x80004005): 与远程主机通信时发生错误。错误代码为0x80070006。]

如何解决这个问题?

string strRequest = Convert.ToString(Request.QueryString.Get("file"));
System.IO.FileInfo file = new System.IO.FileInfo(strRequest);
if (file.Exists)
{
    Response.Clear();
    Response.ContentType = ReturnExtension(System.IO.Path.GetExtension(file.Name));
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + file.Name);
    Response.TransmitFile(strRequest);
    Response.End();
    HttpContext.Current.ApplicationInstance.CompleteRequest();
    //DownloadFile(file.FullName, file.Name);
}

An error occurred while communicating with the remote host. The error code is 0x80070006. - David Heffernan
我猜测这是由于您的共享主机导致的权限问题。 - Security Hound
请告诉我应该给予什么权限? - Salman Roy
8个回答

14

创建一个.bat文件,放入以下命令并运行该文件。它将终止所有现有的Web服务器进程,并应该解决问题。我遇到过同样的问题,这个方法对我有用。非常感谢。

taskkill  /fi "imagename eq webdev.webserver40.exe" 

2
webdev.webserver40.exe是内置于Visual Studio的开发Web服务器,对吧?这会如何帮助呢? - Fishcake
是的,最终完成服务也帮助了我。我手动完成了它。对我来说,真正的原因是“不允许跨线程操作”。Visual Studio的开发服务器在这种情况下失败。我认为运行了多个服务并且出现了跨线程问题。 - Davut Gürbüz
我重新启动了我的Web服务器,这样就停止了异常的发生。但我仍然不确定如何防止这个错误。 - Justin Helgerson

13
我在下面的链接中找到了一个解决方法: http://forums.asp.net/t/1387967.aspx?How+to+create+a+flipcart+like+panel+for+showing+products+in+gridview
if (file.Name == fileName)

{
     Response.ClearContent();
     Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
     Response.AddHeader("Content-Length", file.Length.ToString());
     Response.TransmitFile(file.FullName);
     //Response.End(); Will raise that error. this works well locally but not with IIS
     Response.Flush();//Won't get error with Flush() so use this Instead of End()


}

请注意,当页面执行完成时,Response.End()会自动调用,因此即使您没有显式调用Response.End(),本答案也可能适用。还要注意,在未使用Response.Flush()的情况下使用Response.TransmitFile()在Visual Studio中可以使用,但在IIS上部署时不起作用。 - Oran D. Lord
3
确实,当几乎所有其他方法都无法解决问题时,上述代码能够发挥作用。我本来打算在一个正常运行的生产服务器上与许多活跃用户一起思考IIS用户的问题(谁知道更改用户会导致什么问题)。但现在看来我不必这么做了。真希望我能给你更多的赞! - Иво Недев

3
我刚刚在我们的环境中解决了这个问题。我们开启了模拟身份,并将应用程序池运行为ApplicationPoolIdentity。
问题的原因是应用程序池身份没有读取源文件的权限,尽管模拟用户有访问该文件的权限。解决这个问题的棘手之处在于,如果用户和应用程序池都没有访问权限,则会出现访问权限错误。

2

编辑:我漏掉了页面最初加载正常的部分。我不确定从查询字符串中传递了什么,但您是否尝试使用Server.MapPath?所以,不是

System.IO.FileInfo file = new System.IO.FileInfo(strRequest);

you have

System.IO.FileInfo file = new System.IO.FileInfo(Server.MapPath(strRequest));

如果这有帮助,请告诉我。

不,这不是版本问题。我认为如果是版本问题,整个网站都会出现相同的错误,但事实并非如此。除了这个问题,一切都正常运行。我进一步调查了问题,并发现当我使用Page.Redirect("download.aspx")时会产生此错误。我尝试了另一种方法,在JavaScript弹出窗口中打开download.aspx,它可以正常工作。我仍然无法理解问题所在,这种方法只在Firefox中正常工作,在Internet Explorer中只有弹出窗口打开,下载对话框没有出现:( - Salman Roy

2
在我的情况下,我试图写入和读取这个文件:
var path = System.IO.Path.GetTempFileName();

我使用了下面的代码,它起作用了。我认为IIS用户缺少写入或读取临时文件的权限。
var path = Server.MapPath(@"~\App_Data\Stats");
Directory.CreateDirectory(path);
path = Path.Combine(path, String.Format("{0}.csv", Guid.NewGuid()));

using (var streamWriter = new StreamWriter(path))
using (var csvWriter = new CsvHelper.CsvWriter(streamWriter))
{
    csvWriter.Configuration.Delimiter = csvWriter.Configuration.CultureInfo.TextInfo.ListSeparator;

    csvWriter.WriteRecords(rounds);
}

return File(path, "text/csv", "Stats.csv");

1
如果您的网页中有任何Console.WriteLine或Console.Clear(),并且在非Visual Studio环境下(即部署到IIS时)可能会出现该错误。
如果您在IIS中遇到此问题,在VS中却可以正常工作,则应搜索Console语句并将其删除。

0
在我的情况下,这只发生在特定用户登录时。其他所有用户都可以正常工作。
问题出在用户的LoginEmail中有一个额外的空格。
这发生在一个使用Asp.net Identity和模拟用户身份下载托管服务器上目录中Excel文件的MVC应用程序中。
真是奇怪的事情!

0

重启IIS解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接