訓練
模組
使用 Visual Studio 偵錯工具對 .NET 應用程式進行互動式偵錯 - Training
了解如何使用 Visual Studio 有效率地對 .NET 應用程式進行偵錯,以便快速修正錯誤 (Bug)。 使用 Visual Studio 內的互動式偵錯工具來分析並修正您的 C# 應用程式。
本文說明如何撰寫 CGI 應用程式。
原始產品版本: Visual Basic
原始 KB 編號: 239588
通用閘道介面 (CGI) 應用程式可以使用任何可存取環境變數和 STDIN 或 STDOUT 的程式設計語言撰寫。 由於 Visual Basic 程式設計語言的強大文字處理功能,許多 Web 開發人員想要在 Visual Basic 中撰寫 CGI 程式。 本文說明在 Visual Basic 中撰寫 CGI 應用程式的技巧,並提供簡單的 Visual Basic CGI 範例。
注意
Microsoft 提供的程式設計範例僅供說明之用,並不具任何明示或暗示的責任擔保。 這包括 (但不限於) 任何目的之適售性及適用性的暗示責任擔保。 本文假設您熟悉示範的程式設計語言,也熟悉用以建立和偵錯程序的工具。 Microsoft 技術支援工程師可以協助說明特定程序的功能,但不會修改這些範例以提供附加功能或建構程序來滿足您的特定需求。
若要擷取環境變數,請使用 Environ$
Visual Basic中的函式,如下所示:
VALUE = Environ$(NAME)
注意
NAME 是您想要擷取的環境變數。 其值會在中 VALUE
傳回。
使用 Win32 ReadFile
函式讀取 STDIN
,以及 WriteFile
要寫入 的 STDOUT
函式。 這些函式會要求您提供 或STDOUT
的STDIN
句柄。 您可以使用 函GetStdHandle
式來取得 或 STDOUT
的句柄STDIN
。 在本文中,函式上 GetStdHandle
會使用別名來簡化函式呼叫。 這些函式的宣告如下所示:
Public Declare Function stdin Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_INPUT_HANDLE) As Long
Public Declare Function stdout Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_OUTPUT_HANDLE) As Long
Public Declare Function ReadFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
lpNumberOfBytesRead As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
Public Declare Function WriteFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, _
lpNumberOfBytesWritten As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
傳遞給函式的 GetStdHandle
常數定義為:
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&
如需這些函式中每個參數的定義,請參閱 MSDN 檔。 在下列範例中,CGI 環境變數的完整清單會成為常數。 這會列出 Ctrl-J 上的所有常數。 它也會藉由提供編譯程式和 IntelliSense 驗證來排除程式設計錯誤,但不會妨礙您輸入自己的字串。
為了簡單起見,下列範例會省略錯誤截獲 (Hello.bas):
Option Explicit
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&
Public Const CGI_AUTH_TYPE As String = "AUTH_TYPE"
Public Const CGI_CONTENT_LENGTH As String = "CONTENT_LENGTH"
Public Const CGI_CONTENT_TYPE As String = "CONTENT_TYPE"
Public Const CGI_GATEWAY_INTERFACE As String = "GATEWAY_INTERFACE"
Public Const CGI_HTTP_ACCEPT As String = "HTTP_ACCEPT"
Public Const CGI_HTTP_REFERER As String = "HTTP_REFERER"
Public Const CGI_HTTP_USER_AGENT As String = "HTTP_USER_AGENT"
Public Const CGI_PATH_INFO As String = "PATH_INFO"
Public Const CGI_PATH_TRANSLATED As String = "PATH_TRANSLATED"
Public Const CGI_QUERY_STRING As String = "QUERY_STRING"
Public Const CGI_REMOTE_ADDR As String = "REMOTE_ADDR"
Public Const CGI_REMOTE_HOST As String = "REMOTE_HOST"
Public Const CGI_REMOTE_USER As String = "REMOTE_USER"
Public Const CGI_REQUEST_METHOD As String = "REQUEST_METHOD"
Public Const CGI_SCRIPT_NAME As String = "SCRIPT_NAME"
Public Const CGI_SERVER_NAME As String = "SERVER_NAME"
Public Const CGI_SERVER_PORT As String = "SERVER_PORT"
Public Const CGI_SERVER_PROTOCOL As String = "SERVER_PROTOCOL"
Public Const CGI_SERVER_SOFTWARE As String = "SERVER_SOFTWARE"
Public Declare Function Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long) As Long
Public Declare Function stdin Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_INPUT_HANDLE) As Long
Public Declare Function stdout Lib "kernel32" Alias "GetStdHandle" _
(Optional ByVal Handletype As Long = STD_OUTPUT_HANDLE) As Long
Public Declare Function ReadFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
lpNumberOfBytesRead As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
Public Declare Function WriteFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, _
lpNumberOfBytesWritten As Long, Optional ByVal lpOverlapped As Long = 0&) As Long
Sub Main()
Dim sReadBuffer As String
Dim sWriteBuffer As String
Dim lBytesRead As Long
Dim lBytesWritten As Long
Dim hStdIn As Long
Dim hStdOut As Long
Dim iPos As Integer
' sleep for one minute so the debugger can attach and set a break
' point on line below
' Sleep 60000
sReadBuffer = String$(CLng(Environ$(CGI_CONTENT_LENGTH)), 0)' Get STDIN handle
hStdIn = stdin()' Read client's input
ReadFile hStdIn, sReadBuffer, Len(sReadBuffer), lBytesRead
' Find '=' in the name/value pair and parse the buffer
iPos = InStr(sReadBuffer, "=")
sReadBuffer = Mid$(sReadBuffer, iPos + 1)' Construct and send response to the client
sWriteBuffer = "HTTP/1.0 200 OK" & vbCrLf & "Content-Type: text/html" & _
vbCrLf & vbCrLf & "Hello "
hStdOut = stdout()
WriteFile hStdOut, sWriteBuffer, Len(sWriteBuffer) + 1, lBytesWritten
WriteFile hStdOut, sReadBuffer, Len(sReadBuffer), lBytesWritten
End Sub
測試 CGI 的 HTML 表單 (Test.htm)
<HTML>
<HEAD>
<TITLE>Testing VB CGI</TITLE>
</HEAD>
<BODY>
<FORM action="/cgi-bin/hello.exe" method="POST">
<INPUT TYPE="TEXT" NAME="Name"> Name<BR>
<INPUT TYPE="SUBMIT">
</FORM>
</BODY>
</HTML>
建置 CGI Hello.exe 檔案的步驟:
將新專案建立為標準.exe專案。
從專案移除表單。
將模組新增至專案,並將它命名為 HELLO。
設定 Sub Main
為啟始物件 (項目屬性底下)。
複製上述 Visual Basic 程式代碼,並將其貼到模組。
製作Hello.exe。
注意
範例程式代碼示範如何處理 HTTP POST
要求。 若要處理 GET 要求,CGI 應用程式必須擷取 QUERY_STRING
環境變數。 變數 QUERY_STRING
包含以 和格式 Name=Joe&Color=Red
分隔的名稱/值組。 使用 URL 編碼、所有空白都會轉換成 + ,以及所有特殊字元,例如 ! 會轉換成其 HEX ASCII 值。 換句話說,“Hello, World!” 字符串會表示為 “Hello,+World%21”。Visual Basic CGI 應用程式必須實作所有剖析程序代碼。
因為 CGI 應用程式是由服務啟動,所以可能無法存取網路共用。
請注意,CGI 會以服務的形式執行,這會與伺服器通訊。 因此,可視化介面窗體、控件和消息框完全毫無意義。 事實上,消息框會導致 CGI 應用程式停止回應。
在 Visual Basic 中,應該在整個 CGI 程式代碼中執行錯誤處理,因此不會顯示預設的錯誤消息框。 您可以在伺服器上記錄錯誤訊息,或將它們寫入使用者的瀏覽器。
Visual C 調試程式可以偵錯以 Visual Basic 撰寫的應用程式。 因此,您可以使用下面所參考的 CGI 偵錯技術。 若要使用 Visual C 對 Visual Basic 應用程式進行偵錯,請選擇 [編譯為機器碼],然後選取 [建立符號偵錯資訊] 和 [無優化]。 完成併產生.exe時,Visual C 可以附加至以 Visual Basic 撰寫的執行中 CGI 應用程式。
若要測試 CGI 應用程式,請使用執行許可權將其複製到 IIS 虛擬目錄。
請注意,Visual Basic 程式代碼中的運行時間錯誤或對話框可能會導致 CGI 應用程式停止回應。 如果 CGI 應用程式停止回應,則可以在 Visual Studio 調試程式中執行。
訓練
模組
使用 Visual Studio 偵錯工具對 .NET 應用程式進行互動式偵錯 - Training
了解如何使用 Visual Studio 有效率地對 .NET 應用程式進行偵錯,以便快速修正錯誤 (Bug)。 使用 Visual Studio 內的互動式偵錯工具來分析並修正您的 C# 應用程式。