2019年6月11日 星期二

執行緒已終止


如果你的檔案下載程式,使用者反映每個文字檔的尾巴都會被塞一句「Error」,你會怎麼想?

「這一定是被駭客攻擊了...」

是的,我很想就這麼告訴使用者,但...我真的好心虛,於是,老老實實打開程式碼好好檢查一番。
Partial Class MainPage_FileDownloadSeal
    Inherits CommonPage

    Private Sub MainPage_FileDownloadSeal_Load(sender As Object, e As EventArgs) Handles Me.Load
        Dim wsfile As New AttachFileinfo()

        Try
            Dim FileID As String = Request("File").ToString().Trim()
            Dim ds_file As DataSet = wsfile.getFileBase(FileID)
            Dim strFilePath As String = ds_file.Tables(0).Rows(0)("檔案存放路徑").ToString() + ds_file.Tables(0).Rows(0)("系統檔名").ToString()
            Dim strFileName As String = ds_file.Tables(0).Rows(0)("使用者上傳檔名").ToString()



            If strFilePath.Length <> 0 Then
                If File.Exists(strFilePath) Then
                    If strFilePath.Length > 0 Then
                        Dim strSubName As String

                        strSubName = strFilePath.Substring(strFilePath.LastIndexOf(".") + 1, strFilePath.Length - strFilePath.LastIndexOf(".") - 1)

                        '"檔案分類"

                        Select Case strSubName.ToUpper()
                            Case "TXT"
                                Response.ContentType = "text/html"
                                Exit Select

                            Case "HTM"
                                Response.ContentType = "text/html"
                                Exit Select

                            Case "HTML"
                                Response.ContentType = "text/html"
                                Exit Select

                            Case "DOCX", "DOC"
                                Response.ContentType = "application/msword"
                                Exit Select

                            Case "XLS"
                                Response.ContentType = "application/vnd.ms-excel"
                                Exit Select

                            Case "GIF"
                                Response.ContentType = "image/gif"
                                Exit Select

                            Case "JPG"
                                Response.ContentType = "image/JPG"
                                Exit Select

                            Case "BMP"
                                Response.ContentType = "image/bmp"
                                Exit Select

                            Case "SWF"
                                Response.ContentType = "application/x-shockwave-flash"
                                Exit Select

                            Case "PDF"
                                Response.ContentType = "application/pdf"
                                Exit Select
                            Case Else
                                'specify that the response is a stream that cannot be read by the
                                'client and must be downloaded
                                Response.ContentType = "application/octet-stream"
                                Exit Select
                        End Select



                        Response.Clear()
                        '決定檔案存檔預設名稱
                        Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.UrlEncode(strFileName))
                        Response.WriteFile(strFilePath)
                        Response.[End]()                        
                    End If
                End If
            End If
        Catch ex As Exception
            Response.Write("Error")
        End Try
    End Sub
End Class



這應該再普通不過了吧,別人有的我也有,別人沒加的,我還老實的都有加。你看看,那個 Try ... Catch ,就是我特別力求完整而補上的。

但重點是,別人沒錯,我錯了啊!?


Response.End() 會觸發 ThreadAbortException 造成中斷。若 Response.End() 被 try catch包覆,則會進入 catch 流程。

所以我的程式:
Try
    Response.Clear()
     '決定檔案存檔預設名稱
     Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.UrlEncode(strFileName))
     Response.WriteFile(strFilePath)
     Response.[End]()     
Catch ex As Exception
    Response.Write("Error")
End Try
剛好把 Response.End() 放在 Try 裡頭,當他執行到 Response.End() 時,還沒來的及結束,就先去執行了 Catch 裡面的 Response.Writer("Error")
這也就解釋了,為何我的使用者所下載的檔案尾巴,都會留下一句:Error

所以,正確寫法應該是:
Try
    Response.Clear()
     '決定檔案存檔預設名稱
     Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.UrlEncode(strFileName))
     Response.WriteFile(strFilePath)
Catch ex As Exception
    Response.Write("Error")
Finally
    Response.[End]()
End Try
把 Response.End() 放到 Finally 裡面

2019年6月10日 星期一

不是有效的 Win32 應用程式。 (發生例外狀況於 HRESULT: 0x800700C1)


雖然很不想面對老專案,但過去所缺席的,後面都在排隊等著你。

專案一跑起來,就直接說「不是有效的 Win32 應用程式」,我明明是寫網頁程式的啊,怎麼跟應用程式有關係了。


原來這專案當初是在32位元機器上開發的,現在的PC大都是64位元了,如果你不說,預設上面的應用程式應該都是在 64 位元上執行。只是....,我這包程式裡面不知道有那些地方非得在 32位元才能跑,所以從 IIS 上面下手,讓他支援 32 位元。

為了不影響其他專案,我另外建了一個新的【應用程式集區】


建好後,在 OldProj 應用程式集點選右鍵,選【進階設定】
把【啟用32位元應用程式】設為 True,再選【確定】


最後回到自己的 IIS 網站(例如:PeterTest 之類),選【基本設定】,在裡面把應用程式集改成剛剛新建的 OldProj,
再按【確定】,就可以了。