SQLBatch - исполнитель пакетов SQL-команд. Сгрузить MSI-файл.
Меня раздражают многие программистские микрософтовские инструменты и я написал для себя замену множеству из них, начиная от VS2005. Здесь я расскажу об одной из форм, которую я написал для работы с SQL-сервером. Эта форма вошла частью в общую IDE, которую я написал для работы с SQL-сервером взамен MSSMS. Начиналась эта IDE так.
Эта форма удобна для исполнения инсталляционных скриптов и я ее обычно включаю в инсталляционные пакеты для сложных SQL-инсталляций.
Например, в форму на рисунке снизу загружено порядка ста скриптов. Как видите при инсталляции часть из них выполнилась без ошибок, часть с ошибками. В часности на рисунке видна ошибка с недостаточным доверием SQL к сборке (исправляемая командой ALTER DATABASE xxxx SET TRUSTWORTHY ON).
Эта утилитка позволяет разбить большие инсталляционные скрипты на отдельные фрагменты, увидеть результат выполнения каждого из них и исполнить каждый фрагмент пакетно или по одному. Причем моя утилита может работать сразу с сотнями и тысячами таких SQL-пакетов, в каждом из которых могут быть в свою очередь тысячи отдельных SQL-фрагментов.
Обратите внимание, что скрипты должны быть в юникодовой кодировке, иначе русские буквы потеряются. Скрипты, сохраненные из SMSMS, имеют ANSI-кодировку.
Текст главной формы выглядит так:
00001: Public Class SQLBatch 00002: 00003: #Region "Начальная загрузка дерева и коннект" 00004: 00005: Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 00006: ReadScripts(My.Application.Info.DirectoryPath) 00007: Me.Show() 00008: My.Application.DoEvents() 00009: Call ToolStripButton2_Click(Nothing, Nothing) 00010: End Sub 00011: 00012: Private Sub ToolStripButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton3.Click 00013: Dim SC As New Global.VBNET2000.ServerConnect 00014: SC.ShowDialog() 00015: If SC.ServerConn IsNot Nothing Then 00016: ToolStripTextBox1.Text = CType(SC.ServerConn, Microsoft.SqlServer.Management.Common.ServerConnection).ConnectionString 00017: Dim DB As New Global.SQLBatch.SelectDB(SC.ServerConn) 00018: DB.ShowDialog() 00019: If DB.DBName <> "" Then 00020: ToolStripTextBox1.Text &= ";Initial Catalog=" & DB.DBName & ";" 00021: Try 00022: 'теперь переустановим коннект уже с этой формы для конкретной базы 00023: If CN.State = ConnectionState.Open Then CN.Close() 00024: CN.ConnectionString = ToolStripTextBox1.Text 00025: CN.Open() 00026: CMD.Connection = CN 00027: CMD.CommandTimeout = DB.Timeout 00028: Catch ex As Exception 00029: MsgBox("Ошибка коннекта к базе" & vbCrLf & ex.Message) 00030: End Try 00031: End If 00032: Else 00033: ToolStripTextBox1.Text = "" 00034: End If 00035: End Sub 00036: 00037: Private Sub ToolStripButton2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click 00038: FolderBrowserDialog1.Description = "Выберите директорию со скриптами " & vbcrlf & "(UTF8 или UNICODE)" 00039: FolderBrowserDialog1.SelectedPath = My.Application.Info.DirectoryPath 00040: FolderBrowserDialog1.ShowDialog() 00041: Call ReadScripts(FolderBrowserDialog1.SelectedPath) 00042: End Sub 00043: 00044: Private Sub ReadScripts(ByVal Dir As String) 00045: RichTextBox1.Font = New System.Drawing.Font("Courier", 14, FontStyle.Regular, GraphicsUnit.Pixel) 00046: RichTextBox1.ForeColor = Color.Black 00047: TreeView1.Nodes.Clear() 00048: Dim SQLFragmentNum As Integer = 1 00049: Dim WorkDir As New System.IO.DirectoryInfo(Dir) 00050: For Each OneSQLFile As System.IO.FileInfo In WorkDir.GetFiles("*.sql") 00051: Dim Batch1 As TreeNode = TreeView1.Nodes.Add(OneSQLFile.Name, OneSQLFile.Name, "i1.ico", "i2.ico") 00052: Dim UTF8 As IO.StreamReader = OneSQLFile.OpenText 00053: Dim SQLFragment As New System.Text.StringBuilder 00054: While Not UTF8.EndOfStream 00055: Dim Str1 As String = UTF8.ReadLine 00056: If Str1 = "GO" Then 00057: Dim Tag1 As New System.Collections.Specialized.StringDictionary 00058: Tag1.Add("Raw", SQLFragment.ToString) 00059: Dim Zag As String = SQLFragmentNum.ToString("D3") & ":" & GetBatchName(SQLFragment.ToString) 00060: Dim SQLFragmentNode As TreeNode = Batch1.Nodes.Add(Zag, Zag, "i5.ico", "i0.ico") 00061: SQLFragmentNode.Tag = Tag1 00062: SQLFragment.Length = 0 00063: SQLFragmentNum += 1 00064: Else 00065: SQLFragment.AppendLine(Str1) 00066: End If 00067: End While 00068: UTF8.Close() 00069: Next 00070: End Sub 00071: 00072: Private Sub SQLBatch_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 00073: CN.Close() 00074: End Sub 00075: 00076: #End Region 00077: 00078: #Region "Исполнение запроса" 00079: Dim CN As New Data.SqlClient.SqlConnection 00080: Dim CMD As New SqlClient.SqlCommand 00081: Friend Function SQLExec(ByVal sql As String, ByRef Err1 As String) As Boolean 00082: Try 00083: CMD.CommandText = sql 00084: CMD.ExecuteNonQuery() 00085: 'AddHandler CMD.StatementCompleted, AddressOf CMD_Completed 'все синхронно 00086: Return True 00087: Catch ex As Exception 00088: Err1 = ex.Message 00089: Return False 00090: End Try 00091: End Function 00092: 00093: #End Region 00094: 00095: #Region "Движок по нодам" 00096: 00097: Private Sub GO_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GO.Click 00098: ExecBatch(True) 00099: End Sub 00100: 00101: Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click 00102: ExecBatch(False) 00103: End Sub 00104: 00105: Private Sub ExecBatch(ByVal Packet As Boolean) 00106: My.Application.DoEvents() 00107: Dim StartNodePath As String = TreeView1.Nodes(0).FullPath 00108: Dim Started As Boolean = False 00109: If TreeView1.SelectedNode IsNot Nothing Then StartNodePath = TreeView1.SelectedNode.FullPath 00110: For Each OneSQLFile As TreeNode In TreeView1.Nodes 00111: If OneSQLFile.FullPath = StartNodePath Then Started = True 00112: For Each SQLFragment As TreeNode In OneSQLFile.Nodes 00113: If (SQLFragment.FullPath = StartNodePath) Or Started Then 00114: Started = True 00115: TreeView1.SelectedNode = SQLFragment 00116: Dim Err1 As String = "" 00117: Me.Cursor = Cursors.WaitCursor 00118: If SQLExec(RichTextBox1.Text, Err1) Then 00119: TextBox1.Text = "Command(s) completed successfully." 00120: TreeView1.SelectedNode.ImageKey = "i3.ico" 00121: Else 00122: TextBox1.Text = Err1 00123: TreeView1.SelectedNode.ImageKey = "i4.ico" 00124: End If 00125: CType(TreeView1.SelectedNode.Tag, System.Collections.Specialized.StringDictionary)("res") = TextBox1.Text 00126: Me.Cursor = Cursors.Arrow 00127: If Not Packet Then 00128: TreeView1.SelectedNode = TreeView1.SelectedNode.NextNode 00129: Exit Sub 00130: End If 00131: End If 00132: Next 00133: Next 00134: End Sub 00135: 00136: #End Region 00137: 00138: #Region "Форматирование" 00139: 00140: Private Sub TreeView1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect 00141: Format = True 00142: RichTextBox1.Clear() 00143: If e.Node.Level = 1 Then 00144: If e.Node.Tag IsNot Nothing Then 00145: TextBox1.Text = CType(e.Node.Tag, System.Collections.Specialized.StringDictionary)("res") 00146: If CType(e.Node.Tag, System.Collections.Specialized.StringDictionary)("rtf") Is Nothing Then 00147: Me.Cursor = Cursors.WaitCursor 00148: RichTextBox1.Enabled = False 00149: Dim Raw As String = CType(e.Node.Tag, System.Collections.Specialized.StringDictionary)("raw") 00150: RichTextBox1.AppendText(Raw) 00151: MarkKey(SQLReserved, Color.Blue) 00152: MarkKey(SQLDataType, Color.BlueViolet) 00153: MarkKey(SQLFunction, Color.Magenta) 00154: MarkString(Color.Brown) 00155: MarkComment(Color.Green) 00156: RichTextBox1.Enabled = True 00157: Me.Cursor = Cursors.Arrow 00158: CType(e.Node.Tag, System.Collections.Specialized.StringDictionary)("rtf") = RichTextBox1.Rtf 00159: Else 00160: Dim RTF As String = CType(e.Node.Tag, System.Collections.Specialized.StringDictionary)("rtf") 00161: RichTextBox1.Rtf = RTF 00162: End If 00163: End If 00164: End If 00165: Format = False 00166: End Sub 00167: 00168: Friend Sub MarkKey(ByVal KeyArray() As String, ByVal Color1 As Drawing.Color) 00169: For Each Y As String In KeyArray 00170: Dim StartPos As Integer = 0 00171: Dim Pos1 As Integer = 1 00172: While Pos1 >= 0 00173: Pos1 = RichTextBox1.Find(Y, StartPos, RichTextBoxFinds.WholeWord) 00174: If Pos1 >= 0 Then 00175: RichTextBox1.Select(Pos1, Y.Length) 00176: RichTextBox1.SelectionColor = Color1 00177: StartPos = Pos1 + 1 00178: End If 00179: End While 00180: Next 00181: End Sub 00182: 00183: Friend Sub MarkString(ByVal Color1 As Drawing.Color) 00184: Dim Pos1 As Integer 00185: Dim Pos2 As Integer 00186: While True 00187: Pos1 = RichTextBox1.Find("'", Pos2 + 1, RichTextBoxFinds.None) 00188: If Pos1 >= 0 Then 00189: Pos2 = RichTextBox1.Find("'", Pos1 + 1, RichTextBoxFinds.None) 00190: If Pos2 >= 0 Then 00191: RichTextBox1.Select(Pos1, Pos2 - Pos1 + 1) 00192: RichTextBox1.SelectionColor = Color1 00193: Else 00194: Exit Sub 00195: End If 00196: Else 00197: Exit Sub 00198: End If 00199: End While 00200: End Sub 00201: 00202: Friend Sub MarkComment(ByVal Color1 As Drawing.Color) 00203: Dim NextLinePos As Integer = 0 00204: Dim CurPos As Integer = 0 00205: While True 00206: CurPos = RichTextBox1.Find("--", NextLinePos, RichTextBoxFinds.None) 00207: If CurPos >= 0 Then 00208: Dim CurLine As Integer = RichTextBox1.GetLineFromCharIndex(CurPos) 00209: NextLinePos = RichTextBox1.GetFirstCharIndexFromLine(CurLine + 1) 00210: RichTextBox1.Select(CurPos, NextLinePos - CurPos - 1) 00211: RichTextBox1.SelectionColor = Color1 00212: Else 00213: Exit Sub 00214: End If 00215: End While 00216: End Sub 00217: 00218: Friend Function GetBatchName(ByVal Str1 As String) As String 00219: Dim A() As String 00220: A = Str1.Split(" ") 00221: For Each X As String In A 00222: For Each Y As String In SQLReserved 00223: If String.Compare(X, Y, True) = 0 Then GoTo NewField 00224: Next 00225: Return X.Replace(vbCrLf, "") 00226: NewField: 00227: Next 00228: End Function 00229: 00230: Dim Format As Boolean = False 00231: Private Sub RichTextBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.SelectionChanged 00232: If Not Format Then 00233: RichTextBox1.SelectionBackColor = Color.Yellow 00234: RichTextBox1.SelectionFont = New System.Drawing.Font(RichTextBox1.SelectionFont, FontStyle.Bold) 00235: RichTextBox1.SelectionColor = Color.Red 00236: End If 00237: End Sub 00238: 00239: Private Sub RichTextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged 00240: If Not Format Then 00241: If TreeView1.SelectedNode IsNot Nothing Then 00242: If TreeView1.SelectedNode.Tag IsNot Nothing Then 00243: TreeView1.SelectedNode.ImageKey = "i6.ico" 00244: CType(TreeView1.SelectedNode.Tag, System.Collections.Specialized.StringDictionary)("rtf") = RichTextBox1.Rtf 00245: End If 00246: End If 00247: End If 00248: 00249: End Sub 00250: 00251: #End Region 00252: 00253: #Region "Ключевые слова SQL" 00254: 00255: Dim SQLReserved() As String = {"ADD", "ALL", "ALTER", "AND", "ANY", "AS", "ASC", "AUTHORIZATION", "BACKUP", _ 00256: "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE", "CHECK", "CHECKPOINT", "CLOSE", _ 00257: "CLUSTERED", "COALESCE", "COLLATE", "COLUMN", "COMMIT", "COMPUTE", "CONSTRAINT", "CONTAINS", "CONTAINSTABLE", _ 00258: "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", _ 00259: "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE", "DEFAULT", "DELETE", "DENY", "DESC", _ 00260: "DISK", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMMY", "DUMP", "ELSE", "END", "ERRLVL", "ESCAPE", _ 00261: "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", "FETCH", "FILE", "FILLFACTOR", "FOR", "FOREIGN", "FREETEXT", _ 00262: "FREETEXTTABLE", "FROM", "FULL", "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING", "HOLDLOCK", "IDENTITY", _ 00263: "IDENTITY_INSERT", "IDENTITYCOL", "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN", _ 00264: "KEY", "KILL", "LEFT", "LIKE", "LINENO", "LOAD", "NATIONAL", "NOCHECK", "NONCLUSTERED", "NOT", "NULL", "NULLIF", _ 00265: "OF", "OFF", "OFFSETS", "ON", "OPEN", "OPENDATASOURCE", "OPENQUERY", "OPENROWSET", "OPENXML", "OPTION", "OR", _ 00266: "ORDER", "OUTER", "OVER", "PERCENT", "PLAN", "PRECISION", "PRIMARY", "PRINT", "PROC", "PROCEDURE", "PUBLIC", _ 00267: "RAISERROR", "READ", "READTEXT", "RECONFIGURE", "REFERENCES", "REPLICATION", "RESTORE", "RESTRICT", "RETURN", _ 00268: "REVOKE", "RIGHT", "ROLLBACK", "ROWCOUNT", "ROWGUIDCOL", "RULE", "SAVE", "SCHEMA", "SELECT", "SESSION_USER", _ 00269: "SET", "SETUSER", "SHUTDOWN", "SOME", "STATISTICS", "SYSTEM_USER", "TABLE", "TEXTSIZE", "THEN", "TO", "TOP", _ 00270: "TRAN", "TRANSACTION", "TRIGGER", "TRUNCATE", "TSEQUAL", "UNION", "UNIQUE", "UPDATE", "UPDATETEXT", "USE", _ 00271: "USER", "VALUES", "VARYING", "VIEW", "WAITFOR", "WHEN", "WHERE", "WHILE", "WITH", "WRITETEXT"} 00272: 00273: Dim SQLDataType() As String = {"bigint", "binary", "bit", "char", "cursor", "datetime", "decimal", _ 00274: "float", "image", "int", "money", "nchar", "ntext", "numeric", "nvarchar", "real", "smalldatetime", _ 00275: "smallint", "smallmoney", "sql_variant", "table", "text", "timestamp", "tinyint", "uniqueidentifier", _ 00276: "varbinary", "varchar", "xml"} 00277: 00278: Dim SQLFunction() As String = {"@@TIMETICKS", "@@TOTAL_ERRORS", "@@TOTAL_READ", "@@TOTAL_WRITE", _ 00279: "@@TRANCOUNT", "@@VERSION", "ABS", "ACOS", "APP_NAME", "ASCII", "ASIN", "ASSEMBLYPROPERTY", "ATAN", "ATN2", _ 00280: "AVG", "CASEexpression", "CASTandCONVERT", "CEILING", "CHAR", "CHARINDEX", "CHECKSUM_AGG", "COALESCE", _ 00281: "COL_LENGTH", "COL_NAME", "COLLATIONPROPERTY", "COLUMNPROPERTY", "COLUMNS_UPDATED", "CONTAINSTABLE", _ 00282: "COS", "COT", "COUNT", "COUNT_BIG", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURRENT_USER", "CURSOR_STATUS", _ 00283: "DATABASEPROPERTY", "DATABASEPROPERTYEX", "DATALENGTH", "DATEADD", "DATEDIFF", "DATENAME", "DATEPART", _ 00284: "DAY", "DB_ID", "DB_NAME", "DEGREES", "DENSE_RANK", "DIFFERENCE", "ERROR_LINE", "ERROR_MESSAGE", _ 00285: "ERROR_NUMBER", "ERROR_PROCEDURE", "ERROR_SEVERITY", "ERROR_STATE", "EXP", "FILE_ID", "FILE_IDEX", _ 00286: "FILE_NAME", "FILEGROUP_ID", "FILEGROUP_NAME", "FILEGROUPPROPERTY", "FILEPROPERTY", "FLOOR", _ 00287: "fn_helpcollations", "fn_listextendedproperty", "fn_servershareddrives", "fn_virtualfilestats", _ 00288: "fn_virtualfilestats", "FORMATMESSAGE", "FREETEXTTABLE", "FULLTEXTCATALOGPROPERTY", _ 00289: "FULLTEXTSERVICEPROPERTY", "GETANSINULL", "GETDATE", "GETUTCDATE", "GROUPING", "Has_Perms_By_Name", _ 00290: "HOST_ID", "HOST_NAME", "IDENT_CURRENT", "IDENT_INCR", "IDENT_SEED", "IDENTITY(Function)", "INDEX_COL", _ 00291: "INDEXKEY_PROPERTY", "INDEXPROPERTY", "IS_MEMBER", "IS_SRVROLEMEMBER", "ISDATE", "ISNULL", "ISNUMERIC", _ 00292: "LEFT", "LEN", "LOG", "LOG10", "LOWER", "LTRIM", "MAX", "MIN", "MONTH", "NCHAR", "NEWID", "NTILE", "NULLIF", _ 00293: "OBJECT_ID", "OBJECT_NAME", "OBJECTPROPERTY", "OBJECTPROPERTYEX", "OPENDATASOURCE", "OPENQUERY", _ 00294: "OPENROWSET", "OPENXML", "ORIGINAL_LOGIN", "PARSENAME", "PATINDEX", "PATINDEX", "PERMISSIONS", _ 00295: "PI", "POWER", "QUOTENAME", "RADIANS", "RAND", "RANK", "REPLACE", "REPLICATE", "REVERSE", "RIGHT", _ 00296: "ROUND", "ROW_NUMBER", "ROWCOUNT_BIG", "RTRIM", "SCHEMA_ID", "SCHEMA_NAME", "SCOPE_IDENTITY", _ 00297: "SERVERPROPERTY", "SESSION_USER", "SESSION_USER", "SESSIONPROPERTY", "SETUSER", "SIGN", "SIN", "SOUNDEX", _ 00298: "SPACE", "SQL_VARIANT_PROPERTY", "SQRT", "SQUARE", "STATS_DATE", "STDEV", "STDEVP", "STR", "STUFF", _ 00299: "SUBSTRING", "SUM", "SUSER_ID", "SUSER_NAME", "SUSER_SID", "SUSER_SNAME", "sys.dm_db_index_physical_stats", _ 00300: "sys.fn_builtin_permissions", "SYSTEM_USER", "SYSTEM_USER", "TAN", "TEXTPTR", "TEXTVALID", "TYPE_ID", _ 00301: "TYPE_NAME", "TYPEPROPERTY", "UNICODE", "UPDATE()", "UPPER", "USER_ID", "USER_NAME", "USER_NAME", "VAR", _ 00302: "VARP", "XACT_STATE", "YEAR"} 00303: 00304: #End Region 00305: 00306: 00307: End Class
Соответственно, текст контролов формы выглядит вот так:
00001: <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ 00002: Partial Class SQLBatch 00003: Inherits System.Windows.Forms.Form 00004: 00005: 'Form overrides dispose to clean up the component list. 00006: <System.Diagnostics.DebuggerNonUserCode()> _ 00007: Protected Overrides Sub Dispose(ByVal disposing As Boolean) 00008: Try 00009: If disposing AndAlso components IsNot Nothing Then 00010: components.Dispose() 00011: End If 00012: Finally 00013: MyBase.Dispose(disposing) 00014: End Try 00015: End Sub 00016: 00017: 'Required by the Windows Form Designer 00018: Private components As System.ComponentModel.IContainer 00019: 00020: 'NOTE: The following procedure is required by the Windows Form Designer 00021: 'It can be modified using the Windows Form Designer. 00022: 'Do not modify it using the code editor. 00023: <System.Diagnostics.DebuggerStepThrough()> _ 00024: Private Sub InitializeComponent() 00025: Me.components = New System.ComponentModel.Container 00026: Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SQLBatch)) 00027: Me.ToolStripContainer1 = New System.Windows.Forms.ToolStripContainer 00028: Me.ToolStrip2 = New System.Windows.Forms.ToolStrip 00029: Me.ToolStripButton3 = New System.Windows.Forms.ToolStripButton 00030: Me.ToolStripTextBox1 = New System.Windows.Forms.ToolStripTextBox 00031: Me.SplitContainer1 = New System.Windows.Forms.SplitContainer 00032: Me.TreeView1 = New System.Windows.Forms.TreeView 00033: Me.ImageList1 = New System.Windows.Forms.ImageList(Me.components) 00034: Me.SplitContainer2 = New System.Windows.Forms.SplitContainer 00035: Me.RichTextBox1 = New System.Windows.Forms.RichTextBox 00036: Me.TextBox1 = New System.Windows.Forms.TextBox 00037: Me.ToolStrip1 = New System.Windows.Forms.ToolStrip 00038: Me.GO = New System.Windows.Forms.ToolStripButton 00039: Me.ToolStripButton1 = New System.Windows.Forms.ToolStripButton 00040: Me.ToolStripButton2 = New System.Windows.Forms.ToolStripButton 00041: Me.FolderBrowserDialog1 = New System.Windows.Forms.FolderBrowserDialog 00042: Me.ToolStripSeparator1 = New System.Windows.Forms.ToolStripSeparator 00043: Me.ToolStripContainer1.BottomToolStripPanel.SuspendLayout() 00044: Me.ToolStripContainer1.ContentPanel.SuspendLayout() 00045: Me.ToolStripContainer1.TopToolStripPanel.SuspendLayout() 00046: Me.ToolStripContainer1.SuspendLayout() 00047: Me.ToolStrip2.SuspendLayout() 00048: Me.SplitContainer1.Panel1.SuspendLayout() 00049: Me.SplitContainer1.Panel2.SuspendLayout() 00050: Me.SplitContainer1.SuspendLayout() 00051: Me.SplitContainer2.Panel1.SuspendLayout() 00052: Me.SplitContainer2.Panel2.SuspendLayout() 00053: Me.SplitContainer2.SuspendLayout() 00054: Me.ToolStrip1.SuspendLayout() 00055: Me.SuspendLayout() 00056: ' 00057: 'ToolStripContainer1 00058: ' 00059: ' 00060: 'ToolStripContainer1.BottomToolStripPanel 00061: ' 00062: Me.ToolStripContainer1.BottomToolStripPanel.Controls.Add(Me.ToolStrip2) 00063: ' 00064: 'ToolStripContainer1.ContentPanel 00065: ' 00066: Me.ToolStripContainer1.ContentPanel.Controls.Add(Me.SplitContainer1) 00067: Me.ToolStripContainer1.ContentPanel.Size = New System.Drawing.Size(749, 501) 00068: Me.ToolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill 00069: Me.ToolStripContainer1.Location = New System.Drawing.Point(0, 0) 00070: Me.ToolStripContainer1.Name = "ToolStripContainer1" 00071: Me.ToolStripContainer1.Size = New System.Drawing.Size(749, 551) 00072: Me.ToolStripContainer1.TabIndex = 0 00073: Me.ToolStripContainer1.Text = "ToolStripContainer1" 00074: ' 00075: 'ToolStripContainer1.TopToolStripPanel 00076: ' 00077: Me.ToolStripContainer1.TopToolStripPanel.Controls.Add(Me.ToolStrip1) 00078: ' 00079: 'ToolStrip2 00080: ' 00081: Me.ToolStrip2.Dock = System.Windows.Forms.DockStyle.None 00082: Me.ToolStrip2.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ToolStripButton3, Me.ToolStripTextBox1}) 00083: Me.ToolStrip2.Location = New System.Drawing.Point(3, 0) 00084: Me.ToolStrip2.Name = "ToolStrip2" 00085: Me.ToolStrip2.Size = New System.Drawing.Size(535, 25) 00086: Me.ToolStrip2.TabIndex = 1 00087: ' 00088: 'ToolStripButton3 00089: ' 00090: Me.ToolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image 00091: Me.ToolStripButton3.Image = CType(resources.GetObject("ToolStripButton3.Image"), System.Drawing.Image) 00092: Me.ToolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta 00093: Me.ToolStripButton3.Name = "ToolStripButton3" 00094: Me.ToolStripButton3.Size = New System.Drawing.Size(23, 22) 00095: Me.ToolStripButton3.Text = "Переконнектится к SQL-серверу" 00096: ' 00097: 'ToolStripTextBox1 00098: ' 00099: Me.ToolStripTextBox1.BackColor = System.Drawing.SystemColors.InactiveBorder 00100: Me.ToolStripTextBox1.Name = "ToolStripTextBox1" 00101: Me.ToolStripTextBox1.Size = New System.Drawing.Size(500, 25) 00102: Me.ToolStripTextBox1.ToolTipText = "Текущий ConnectionString" 00103: ' 00104: 'SplitContainer1 00105: ' 00106: Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill 00107: Me.SplitContainer1.Location = New System.Drawing.Point(0, 0) 00108: Me.SplitContainer1.Name = "SplitContainer1" 00109: ' 00110: 'SplitContainer1.Panel1 00111: ' 00112: Me.SplitContainer1.Panel1.Controls.Add(Me.TreeView1) 00113: ' 00114: 'SplitContainer1.Panel2 00115: ' 00116: Me.SplitContainer1.Panel2.Controls.Add(Me.SplitContainer2) 00117: Me.SplitContainer1.Size = New System.Drawing.Size(749, 501) 00118: Me.SplitContainer1.SplitterDistance = 188 00119: Me.SplitContainer1.TabIndex = 0 00120: ' 00121: 'TreeView1 00122: ' 00123: Me.TreeView1.Dock = System.Windows.Forms.DockStyle.Fill 00124: Me.TreeView1.ImageKey = "i179.ico" 00125: Me.TreeView1.ImageList = Me.ImageList1 00126: Me.TreeView1.Location = New System.Drawing.Point(0, 0) 00127: Me.TreeView1.Name = "TreeView1" 00128: Me.TreeView1.SelectedImageIndex = 0 00129: Me.TreeView1.Size = New System.Drawing.Size(188, 501) 00130: Me.TreeView1.TabIndex = 0 00131: ' 00132: 'ImageList1 00133: ' 00134: Me.ImageList1.ImageStream = CType(resources.GetObject("ImageList1.ImageStream"), System.Windows.Forms.ImageListStreamer) 00135: Me.ImageList1.TransparentColor = System.Drawing.Color.Transparent 00136: Me.ImageList1.Images.SetKeyName(0, "i0.ico") 00137: Me.ImageList1.Images.SetKeyName(1, "i1.ico") 00138: Me.ImageList1.Images.SetKeyName(2, "i2.ico") 00139: Me.ImageList1.Images.SetKeyName(3, "i3.ico") 00140: Me.ImageList1.Images.SetKeyName(4, "i4.ico") 00141: Me.ImageList1.Images.SetKeyName(5, "i5.ico") 00142: Me.ImageList1.Images.SetKeyName(6, "i6.ico") 00143: ' 00144: 'SplitContainer2 00145: ' 00146: Me.SplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill 00147: Me.SplitContainer2.Location = New System.Drawing.Point(0, 0) 00148: Me.SplitContainer2.Name = "SplitContainer2" 00149: Me.SplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal 00150: ' 00151: 'SplitContainer2.Panel1 00152: ' 00153: Me.SplitContainer2.Panel1.Controls.Add(Me.RichTextBox1) 00154: ' 00155: 'SplitContainer2.Panel2 00156: ' 00157: Me.SplitContainer2.Panel2.Controls.Add(Me.TextBox1) 00158: Me.SplitContainer2.Size = New System.Drawing.Size(557, 501) 00159: Me.SplitContainer2.SplitterDistance = 393 00160: Me.SplitContainer2.TabIndex = 0 00161: ' 00162: 'RichTextBox1 00163: ' 00164: Me.RichTextBox1.Dock = System.Windows.Forms.DockStyle.Fill 00165: Me.RichTextBox1.Location = New System.Drawing.Point(0, 0) 00166: Me.RichTextBox1.Name = "RichTextBox1" 00167: Me.RichTextBox1.Size = New System.Drawing.Size(557, 393) 00168: Me.RichTextBox1.TabIndex = 0 00169: Me.RichTextBox1.Text = "" 00170: ' 00171: 'TextBox1 00172: ' 00173: Me.TextBox1.Dock = System.Windows.Forms.DockStyle.Fill 00174: Me.TextBox1.Location = New System.Drawing.Point(0, 0) 00175: Me.TextBox1.Multiline = True 00176: Me.TextBox1.Name = "TextBox1" 00177: Me.TextBox1.Size = New System.Drawing.Size(557, 104) 00178: Me.TextBox1.TabIndex = 0 00179: ' 00180: 'ToolStrip1 00181: ' 00182: Me.ToolStrip1.Dock = System.Windows.Forms.DockStyle.None 00183: Me.ToolStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.GO, Me.ToolStripButton1, Me.ToolStripSeparator1, Me.ToolStripButton2}) 00184: Me.ToolStrip1.Location = New System.Drawing.Point(3, 0) 00185: Me.ToolStrip1.Name = "ToolStrip1" 00186: Me.ToolStrip1.Size = New System.Drawing.Size(116, 25) 00187: Me.ToolStrip1.TabIndex = 0 00188: ' 00189: 'GO 00190: ' 00191: Me.GO.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image 00192: Me.GO.Image = CType(resources.GetObject("GO.Image"), System.Drawing.Image) 00193: Me.GO.ImageTransparentColor = System.Drawing.Color.Magenta 00194: Me.GO.Name = "GO" 00195: Me.GO.Size = New System.Drawing.Size(23, 22) 00196: Me.GO.Text = "GO" 00197: Me.GO.ToolTipText = "Выполнить все пакетно" 00198: ' 00199: 'ToolStripButton1 00200: ' 00201: Me.ToolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image 00202: Me.ToolStripButton1.Image = CType(resources.GetObject("ToolStripButton1.Image"), System.Drawing.Image) 00203: Me.ToolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta 00204: Me.ToolStripButton1.Name = "ToolStripButton1" 00205: Me.ToolStripButton1.Size = New System.Drawing.Size(23, 22) 00206: Me.ToolStripButton1.Text = "ToolStripButton1" 00207: Me.ToolStripButton1.ToolTipText = "Выполнить текущий скрипт" 00208: ' 00209: 'ToolStripButton2 00210: ' 00211: Me.ToolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image 00212: Me.ToolStripButton2.Image = CType(resources.GetObject("ToolStripButton2.Image"), System.Drawing.Image) 00213: Me.ToolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta 00214: Me.ToolStripButton2.Name = "ToolStripButton2" 00215: Me.ToolStripButton2.Size = New System.Drawing.Size(23, 22) 00216: Me.ToolStripButton2.Text = "ToolStripButton2" 00217: Me.ToolStripButton2.ToolTipText = "Пересчитать скрипты заново (кодировка скриптов UTF8 или UNICODE)" 00218: ' 00219: 'ToolStripSeparator1 00220: ' 00221: Me.ToolStripSeparator1.Name = "ToolStripSeparator1" 00222: Me.ToolStripSeparator1.Size = New System.Drawing.Size(6, 25) 00223: ' 00224: 'SQLBatch 00225: ' 00226: Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) 00227: Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font 00228: Me.ClientSize = New System.Drawing.Size(749, 551) 00229: Me.Controls.Add(Me.ToolStripContainer1) 00230: Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) 00231: Me.Name = "SQLBatch" 00232: Me.Text = "SQLBatch (by VBNET2000)" 00233: Me.ToolStripContainer1.BottomToolStripPanel.ResumeLayout(False) 00234: Me.ToolStripContainer1.BottomToolStripPanel.PerformLayout() 00235: Me.ToolStripContainer1.ContentPanel.ResumeLayout(False) 00236: Me.ToolStripContainer1.TopToolStripPanel.ResumeLayout(False) 00237: Me.ToolStripContainer1.TopToolStripPanel.PerformLayout() 00238: Me.ToolStripContainer1.ResumeLayout(False) 00239: Me.ToolStripContainer1.PerformLayout() 00240: Me.ToolStrip2.ResumeLayout(False) 00241: Me.ToolStrip2.PerformLayout() 00242: Me.SplitContainer1.Panel1.ResumeLayout(False) 00243: Me.SplitContainer1.Panel2.ResumeLayout(False) 00244: Me.SplitContainer1.ResumeLayout(False) 00245: Me.SplitContainer2.Panel1.ResumeLayout(False) 00246: Me.SplitContainer2.Panel2.ResumeLayout(False) 00247: Me.SplitContainer2.Panel2.PerformLayout() 00248: Me.SplitContainer2.ResumeLayout(False) 00249: Me.ToolStrip1.ResumeLayout(False) 00250: Me.ToolStrip1.PerformLayout() 00251: Me.ResumeLayout(False) 00252: 00253: End Sub 00254: Friend WithEvents ToolStripContainer1 As System.Windows.Forms.ToolStripContainer 00255: Friend WithEvents SplitContainer1 As System.Windows.Forms.SplitContainer 00256: Friend WithEvents TreeView1 As System.Windows.Forms.TreeView 00257: Friend WithEvents SplitContainer2 As System.Windows.Forms.SplitContainer 00258: Friend WithEvents RichTextBox1 As System.Windows.Forms.RichTextBox 00259: Friend WithEvents TextBox1 As System.Windows.Forms.TextBox 00260: Friend WithEvents ToolStrip1 As System.Windows.Forms.ToolStrip 00261: Friend WithEvents ImageList1 As System.Windows.Forms.ImageList 00262: Friend WithEvents GO As System.Windows.Forms.ToolStripButton 00263: Friend WithEvents ToolStripButton1 As System.Windows.Forms.ToolStripButton 00264: Friend WithEvents ToolStrip2 As System.Windows.Forms.ToolStrip 00265: Friend WithEvents ToolStripButton3 As System.Windows.Forms.ToolStripButton 00266: Friend WithEvents ToolStripTextBox1 As System.Windows.Forms.ToolStripTextBox 00267: Friend WithEvents ToolStripButton2 As System.Windows.Forms.ToolStripButton 00268: Friend WithEvents FolderBrowserDialog1 As System.Windows.Forms.FolderBrowserDialog 00269: Friend WithEvents ToolStripSeparator1 As System.Windows.Forms.ToolStripSeparator 00270: 00271: End Class
Текст вот этой маленькой формы выглядит вот так:
00001: Public Class SelectDB 00002: Friend _ServerConnction As Microsoft.SqlServer.Management.Common.ServerConnection 00003: Public DBName As String 00004: Public Timeout As Integer 00005: Private Sub SelectDB_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 00006: Dim RDR As Data.SqlClient.SqlDataReader = _ServerConnction.ExecuteReader("select * from sys.databases") 00007: While RDR.Read 00008: ComboBox1.Items.Add(RDR(0)) 00009: End While 00010: RDR.Close() 00011: ComboBox1.SelectedIndex = 0 00012: End Sub 00013: 00014: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 00015: DBName = ComboBox1.Text 00016: Me.Close() 00017: End Sub 00018: 00019: Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 00020: Timeout = NumericUpDown1.Value 00021: End Sub 00022: End Class
А текст ее контролов вот так:
00001: <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ 00002: Partial Class SelectDB 00003: Inherits System.Windows.Forms.Form 00004: 00005: 'Form overrides dispose to clean up the component list. 00006: <System.Diagnostics.DebuggerNonUserCode()> _ 00007: Protected Overrides Sub Dispose(ByVal disposing As Boolean) 00008: Try 00009: If disposing AndAlso components IsNot Nothing Then 00010: components.Dispose() 00011: End If 00012: Finally 00013: MyBase.Dispose(disposing) 00014: End Try 00015: End Sub 00016: 00017: 'Required by the Windows Form Designer 00018: Private components As System.ComponentModel.IContainer 00019: 00020: 'NOTE: The following procedure is required by the Windows Form Designer 00021: 'It can be modified using the Windows Form Designer. 00022: 'Do not modify it using the code editor. 00023: <System.Diagnostics.DebuggerStepThrough()> _ 00024: Private Sub InitializeComponent() 00025: Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SelectDB)) 00026: Me.ComboBox1 = New System.Windows.Forms.ComboBox 00027: Me.Button1 = New System.Windows.Forms.Button 00028: Me.Label1 = New System.Windows.Forms.Label 00029: Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown 00030: CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit() 00031: Me.SuspendLayout() 00032: ' 00033: 'ComboBox1 00034: ' 00035: Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList 00036: Me.ComboBox1.FormattingEnabled = True 00037: Me.ComboBox1.Location = New System.Drawing.Point(12, 26) 00038: Me.ComboBox1.Name = "ComboBox1" 00039: Me.ComboBox1.Size = New System.Drawing.Size(300, 21) 00040: Me.ComboBox1.TabIndex = 0 00041: ' 00042: 'Button1 00043: ' 00044: Me.Button1.Location = New System.Drawing.Point(318, 26) 00045: Me.Button1.Name = "Button1" 00046: Me.Button1.Size = New System.Drawing.Size(79, 23) 00047: Me.Button1.TabIndex = 1 00048: Me.Button1.Text = "Select" 00049: Me.Button1.UseVisualStyleBackColor = True 00050: ' 00051: 'Label1 00052: ' 00053: Me.Label1.AutoSize = True 00054: Me.Label1.Location = New System.Drawing.Point(104, 72) 00055: Me.Label1.Name = "Label1" 00056: Me.Label1.Size = New System.Drawing.Size(121, 13) 00057: Me.Label1.TabIndex = 3 00058: Me.Label1.Text = "Command Timeout (sec)" 00059: ' 00060: 'NumericUpDown1 00061: ' 00062: Me.NumericUpDown1.Location = New System.Drawing.Point(12, 65) 00063: Me.NumericUpDown1.Name = "NumericUpDown1" 00064: Me.NumericUpDown1.Size = New System.Drawing.Size(74, 20) 00065: Me.NumericUpDown1.TabIndex = 4 00066: Me.NumericUpDown1.Value = New Decimal(New Integer() {10, 0, 0, 0}) 00067: ' 00068: 'SelectDB 00069: ' 00070: Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) 00071: Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font 00072: Me.ClientSize = New System.Drawing.Size(414, 190) 00073: Me.Controls.Add(Me.NumericUpDown1) 00074: Me.Controls.Add(Me.Label1) 00075: Me.Controls.Add(Me.Button1) 00076: Me.Controls.Add(Me.ComboBox1) 00077: Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) 00078: Me.Name = "SelectDB" 00079: Me.Text = "Connect to DB ..." 00080: CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit() 00081: Me.ResumeLayout(False) 00082: Me.PerformLayout() 00083: 00084: End Sub 00085: Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox 00086: Friend WithEvents Button1 As System.Windows.Forms.Button 00087: 00088: 00089: Public Sub New(ByVal ServerConnction As Microsoft.SqlServer.Management.Common.ServerConnection) 00090: _ServerConnction = ServerConnction 00091: ' This call is required by the Windows Form Designer. 00092: InitializeComponent() 00093: ' Add any initialization after the InitializeComponent() call. 00094: End Sub 00095: Friend WithEvents Label1 As System.Windows.Forms.Label 00096: Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown 00097: End Class
А текст формы коннекта к SQL (расположенной на переднем плане) выглядит вот так:
00001: Public Class ServerConnect 00002: Public ServerConn As ServerConnection 00003: Private bError As Boolean 00004: 00005: Public Sub New(ByVal connection As ServerConnection) 00006: InitializeComponent() 00007: ServerConn = connection 00008: End Sub 00009: 00010: Private Sub ServerConnect_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 00011: Me.Show() 00012: My.Application.DoEvents() 00013: GetServerList() 00014: ProcessWindowsAuthentication() 00015: End Sub 00016: 00017: Private Sub WindowsAuthenticationRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles WindowsAuthenticationRadioButton.CheckedChanged 00018: ProcessWindowsAuthentication() 00019: End Sub 00020: 00021: Private Sub ProcessWindowsAuthentication() 00022: If WindowsAuthenticationRadioButton.Checked = True Then 00023: UserNameTextBox.Enabled = False 00024: PasswordTextBox.Enabled = False 00025: Else 00026: UserNameTextBox.Enabled = True 00027: PasswordTextBox.Enabled = True 00028: End If 00029: End Sub 00030: 00031: Private Sub ConnectCommandButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectCommandButton.Click 00032: Dim csr As Cursor = Nothing 00033: Try 00034: csr = Me.Cursor 00035: Me.Cursor = Cursors.WaitCursor 00036: bError = False ' 00037: If ServerConn Is Nothing Then 00038: ServerConn = New ServerConnection 00039: End If 00040: ServerConn.ServerInstance = ServerNamesComboBox.Text 00041: ServerConn.SqlExecutionModes = SqlExecutionModes.ExecuteAndCaptureSql 00042: ServerConn.ConnectTimeout = CType(TimeoutUpDown.Value, Int32) 00043: If WindowsAuthenticationRadioButton.Checked = True Then 00044: ServerConn.LoginSecure = True 00045: Else 00046: ServerConn.LoginSecure = False 00047: ServerConn.Login = UserNameTextBox.Text 00048: ServerConn.Password = PasswordTextBox.Text 00049: End If 00050: 00051: If DisplayEventsCheckBox.CheckState = CheckState.Checked Then 00052: AddHandler ServerConn.InfoMessage, AddressOf OnSqlInfoMessage 00053: AddHandler ServerConn.ServerMessage, AddressOf OnServerMessage 00054: AddHandler ServerConn.SqlConnectionObject.StateChange, AddressOf OnStateChange 00055: AddHandler ServerConn.StatementExecuted, AddressOf OnStatementExecuted 00056: End If 00057: ServerConn.Connect() 00058: Catch ex As ConnectionFailureException 00059: Dim emb As New ExceptionMessageBox(ex) 00060: emb.Show(Me) 00061: bError = True 00062: Catch ex As SmoException 00063: Dim emb As New ExceptionMessageBox(ex) 00064: emb.Show(Me) 00065: bError = True 00066: Finally 00067: Me.Cursor = csr 00068: End Try 00069: End Sub 00070: 00071: Private Sub CancelCommandButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CancelCommandButton.Click 00072: ServerConn = Nothing 00073: Me.Close() 00074: End Sub 00075: 00076: Private Sub GetServerList() 00077: Dim dt As DataTable = SmoApplication.EnumAvailableSqlServers(False) 00078: If dt Is Nothing Then Exit Sub 00079: If (dt.Rows.Count > 0) Then 00080: For Each dr As DataRow In dt.Rows 00081: ServerNamesComboBox.Items.Add(dr("Name")) 00082: Next 00083: ServerNamesComboBox.SelectedIndex = ServerNamesComboBox.FindStringExact(Environment.MachineName) 00084: If (ServerNamesComboBox.SelectedIndex < 0) Then ServerNamesComboBox.SelectedIndex = 0 00085: Else 00086: Dim emb As New ExceptionMessageBox() 00087: emb.Text = My.Resources.NoSqlServers 00088: emb.Show(Me) 00089: End If 00090: End Sub 00091: 00092: Private Sub OnSqlInfoMessage(ByVal sender As Object, ByVal args As System.Data.SqlClient.SqlInfoMessageEventArgs) 00093: Dim err As SqlError 00094: Dim emb As ExceptionMessageBox 00095: For Each err In args.Errors 00096: emb = New ExceptionMessageBox() 00097: emb.Text = String.Format(System.Globalization.CultureInfo.InvariantCulture, My.Resources.SqlError, err.Source, err.Class, err.State, err.Number, err.LineNumber, err.Procedure, err.Server, err.Message) 00098: emb.Show(Me) 00099: Next 00100: End Sub 00101: 00102: Private Sub OnServerMessage(ByVal sender As Object, ByVal args As ServerMessageEventArgs) 00103: Dim err As SqlError = args.Error 00104: Dim emb As New ExceptionMessageBox() 00105: emb.Text = String.Format(System.Globalization.CultureInfo.InvariantCulture, _ 00106: My.Resources.SqlError, err.Source, err.Class, err.State, err.Number, err.LineNumber, err.Procedure, err.Server, err.Message) 00107: emb.Show(Me) 00108: End Sub 00109: 00110: Private Sub OnStateChange(ByVal sender As Object, ByVal args As StateChangeEventArgs) 00111: If (Me.IsDisposed = False) Then 00112: Dim emb As New ExceptionMessageBox() 00113: emb.Text = String.Format(System.Globalization.CultureInfo.InvariantCulture, My.Resources.StateChanged, args.OriginalState.ToString(), args.CurrentState.ToString()) 00114: emb.Show(Me) 00115: End If 00116: End Sub 00117: 00118: Private Sub OnStatementExecuted(ByVal sender As Object, ByVal args As StatementEventArgs) 00119: Dim emb As New ExceptionMessageBox() 00120: emb.Text = args.SqlStatement 00121: emb.Show(Me) 00122: End Sub 00123: 00124: Private Sub ServerConnect_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing 00125: If bError = True Then e.Cancel = True 00126: bError = False 00127: End Sub 00128: 00129: End Class
Текст контролов форрмы коннекта выглядит вот так:
00001: Public Partial Class ServerConnect 00002: Inherits System.Windows.Forms.Form 00003: 00004: <System.Diagnostics.DebuggerNonUserCode()> _ 00005: Public Sub New() 00006: MyBase.New() 00007: 00008: 'This call is required by the Windows Form Designer. 00009: InitializeComponent() 00010: End Sub 00011: 00012: 'Form overrides dispose to clean up the component list. 00013: <System.Diagnostics.DebuggerNonUserCode()> _ 00014: Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) 00015: If disposing AndAlso components IsNot Nothing Then 00016: components.Dispose() 00017: End If 00018: MyBase.Dispose(disposing) 00019: End Sub 00020: 00021: 'Required by the Windows Form Designer 00022: Private components As System.ComponentModel.IContainer 00023: 00024: 'NOTE: The following procedure is required by the Windows Form Designer 00025: 'It can be modified using the Windows Form Designer. 00026: 'Do not modify it using the code editor. 00027: <System.Diagnostics.DebuggerStepThrough()> _ 00028: Private Sub InitializeComponent() 00029: Me.components = New System.ComponentModel.Container 00030: Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ServerConnect)) 00031: Me.SecurityPanel = New System.Windows.Forms.Panel 00032: Me.radioButton2 = New System.Windows.Forms.RadioButton 00033: Me.WindowsAuthenticationRadioButton = New System.Windows.Forms.RadioButton 00034: Me.SecondsLabel = New System.Windows.Forms.Label 00035: Me.ServerNamesComboBox = New System.Windows.Forms.ComboBox 00036: Me.toolTip1 = New System.Windows.Forms.ToolTip(Me.components) 00037: Me.TimeoutUpDown = New System.Windows.Forms.NumericUpDown 00038: Me.AuthenticationLabel = New System.Windows.Forms.Label 00039: Me.DisplayEventsCheckBox = New System.Windows.Forms.CheckBox 00040: Me.ConnectTimeoutLabel = New System.Windows.Forms.Label 00041: Me.CancelCommandButton = New System.Windows.Forms.Button 00042: Me.ConnectCommandButton = New System.Windows.Forms.Button 00043: Me.PasswordTextBox = New System.Windows.Forms.TextBox 00044: Me.UserNameTextBox = New System.Windows.Forms.TextBox 00045: Me.PasswordLabel = New System.Windows.Forms.Label 00046: Me.UserNameLabel = New System.Windows.Forms.Label 00047: Me.ServerNameLabel = New System.Windows.Forms.Label 00048: Me.label1 = New System.Windows.Forms.Label 00049: Me.SecurityPanel.SuspendLayout() 00050: CType(Me.TimeoutUpDown, System.ComponentModel.ISupportInitialize).BeginInit() 00051: Me.SuspendLayout() 00052: ' 00053: 'SecurityPanel 00054: ' 00055: Me.SecurityPanel.Controls.Add(Me.radioButton2) 00056: Me.SecurityPanel.Controls.Add(Me.WindowsAuthenticationRadioButton) 00057: resources.ApplyResources(Me.SecurityPanel, "SecurityPanel") 00058: Me.SecurityPanel.Name = "SecurityPanel" 00059: ' 00060: 'radioButton2 00061: ' 00062: resources.ApplyResources(Me.radioButton2, "radioButton2") 00063: Me.radioButton2.Name = "radioButton2" 00064: ' 00065: 'WindowsAuthenticationRadioButton 00066: ' 00067: Me.WindowsAuthenticationRadioButton.Checked = True 00068: resources.ApplyResources(Me.WindowsAuthenticationRadioButton, "WindowsAuthenticationRadioButton") 00069: Me.WindowsAuthenticationRadioButton.Name = "WindowsAuthenticationRadioButton" 00070: Me.WindowsAuthenticationRadioButton.TabStop = True 00071: ' 00072: 'SecondsLabel 00073: ' 00074: resources.ApplyResources(Me.SecondsLabel, "SecondsLabel") 00075: Me.SecondsLabel.Name = "SecondsLabel" 00076: ' 00077: 'ServerNamesComboBox 00078: ' 00079: Me.ServerNamesComboBox.FormattingEnabled = True 00080: resources.ApplyResources(Me.ServerNamesComboBox, "ServerNamesComboBox") 00081: Me.ServerNamesComboBox.Name = "ServerNamesComboBox" 00082: Me.ServerNamesComboBox.Sorted = True 00083: ' 00084: 'TimeoutUpDown 00085: ' 00086: resources.ApplyResources(Me.TimeoutUpDown, "TimeoutUpDown") 00087: Me.TimeoutUpDown.Name = "TimeoutUpDown" 00088: Me.TimeoutUpDown.Value = New Decimal(New Integer() {15, 0, 0, 0}) 00089: ' 00090: 'AuthenticationLabel 00091: ' 00092: resources.ApplyResources(Me.AuthenticationLabel, "AuthenticationLabel") 00093: Me.AuthenticationLabel.Name = "AuthenticationLabel" 00094: ' 00095: 'DisplayEventsCheckBox 00096: ' 00097: resources.ApplyResources(Me.DisplayEventsCheckBox, "DisplayEventsCheckBox") 00098: Me.DisplayEventsCheckBox.Name = "DisplayEventsCheckBox" 00099: ' 00100: 'ConnectTimeoutLabel 00101: ' 00102: resources.ApplyResources(Me.ConnectTimeoutLabel, "ConnectTimeoutLabel") 00103: Me.ConnectTimeoutLabel.Name = "ConnectTimeoutLabel" 00104: ' 00105: 'CancelCommandButton 00106: ' 00107: Me.CancelCommandButton.DialogResult = System.Windows.Forms.DialogResult.Cancel 00108: resources.ApplyResources(Me.CancelCommandButton, "CancelCommandButton") 00109: Me.CancelCommandButton.Name = "CancelCommandButton" 00110: ' 00111: 'ConnectCommandButton 00112: ' 00113: Me.ConnectCommandButton.DialogResult = System.Windows.Forms.DialogResult.OK 00114: resources.ApplyResources(Me.ConnectCommandButton, "ConnectCommandButton") 00115: Me.ConnectCommandButton.Name = "ConnectCommandButton" 00116: ' 00117: 'PasswordTextBox 00118: ' 00119: resources.ApplyResources(Me.PasswordTextBox, "PasswordTextBox") 00120: Me.PasswordTextBox.Name = "PasswordTextBox" 00121: ' 00122: 'UserNameTextBox 00123: ' 00124: resources.ApplyResources(Me.UserNameTextBox, "UserNameTextBox") 00125: Me.UserNameTextBox.Name = "UserNameTextBox" 00126: ' 00127: 'PasswordLabel 00128: ' 00129: resources.ApplyResources(Me.PasswordLabel, "PasswordLabel") 00130: Me.PasswordLabel.Name = "PasswordLabel" 00131: ' 00132: 'UserNameLabel 00133: ' 00134: resources.ApplyResources(Me.UserNameLabel, "UserNameLabel") 00135: Me.UserNameLabel.Name = "UserNameLabel" 00136: ' 00137: 'ServerNameLabel 00138: ' 00139: resources.ApplyResources(Me.ServerNameLabel, "ServerNameLabel") 00140: Me.ServerNameLabel.Name = "ServerNameLabel" 00141: ' 00142: 'label1 00143: ' 00144: resources.ApplyResources(Me.label1, "label1") 00145: Me.label1.Name = "label1" 00146: ' 00147: 'ServerConnect 00148: ' 00149: Me.AcceptButton = Me.ConnectCommandButton 00150: resources.ApplyResources(Me, "$this") 00151: Me.CancelButton = Me.CancelCommandButton 00152: Me.Controls.Add(Me.label1) 00153: Me.Controls.Add(Me.SecondsLabel) 00154: Me.Controls.Add(Me.ServerNamesComboBox) 00155: Me.Controls.Add(Me.TimeoutUpDown) 00156: Me.Controls.Add(Me.AuthenticationLabel) 00157: Me.Controls.Add(Me.DisplayEventsCheckBox) 00158: Me.Controls.Add(Me.ConnectTimeoutLabel) 00159: Me.Controls.Add(Me.CancelCommandButton) 00160: Me.Controls.Add(Me.ConnectCommandButton) 00161: Me.Controls.Add(Me.PasswordTextBox) 00162: Me.Controls.Add(Me.UserNameTextBox) 00163: Me.Controls.Add(Me.PasswordLabel) 00164: Me.Controls.Add(Me.UserNameLabel) 00165: Me.Controls.Add(Me.ServerNameLabel) 00166: Me.Controls.Add(Me.SecurityPanel) 00167: Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog 00168: Me.MaximizeBox = False 00169: Me.MinimizeBox = False 00170: Me.Name = "ServerConnect" 00171: Me.ShowInTaskbar = False 00172: Me.SecurityPanel.ResumeLayout(False) 00173: CType(Me.TimeoutUpDown, System.ComponentModel.ISupportInitialize).EndInit() 00174: Me.ResumeLayout(False) 00175: Me.PerformLayout() 00176: 00177: End Sub 00178: Friend WithEvents SecurityPanel As System.Windows.Forms.Panel 00179: Friend WithEvents radioButton2 As System.Windows.Forms.RadioButton 00180: Friend WithEvents WindowsAuthenticationRadioButton As System.Windows.Forms.RadioButton 00181: Friend WithEvents SecondsLabel As System.Windows.Forms.Label 00182: Friend WithEvents ServerNamesComboBox As System.Windows.Forms.ComboBox 00183: Friend WithEvents toolTip1 As System.Windows.Forms.ToolTip 00184: Friend WithEvents TimeoutUpDown As System.Windows.Forms.NumericUpDown 00185: Friend WithEvents AuthenticationLabel As System.Windows.Forms.Label 00186: Friend WithEvents DisplayEventsCheckBox As System.Windows.Forms.CheckBox 00187: Friend WithEvents ConnectTimeoutLabel As System.Windows.Forms.Label 00188: Friend WithEvents CancelCommandButton As System.Windows.Forms.Button 00189: Friend WithEvents ConnectCommandButton As System.Windows.Forms.Button 00190: Friend WithEvents PasswordTextBox As System.Windows.Forms.TextBox 00191: Friend WithEvents UserNameTextBox As System.Windows.Forms.TextBox 00192: Friend WithEvents PasswordLabel As System.Windows.Forms.Label 00193: Friend WithEvents UserNameLabel As System.Windows.Forms.Label 00194: Friend WithEvents ServerNameLabel As System.Windows.Forms.Label 00195: Friend WithEvents label1 As System.Windows.Forms.Label 00196: End Class
Текст формы коннекта к серверу стандартный, используется во многих случаях в моей IDE, поэтому выбор базы вынесен на отдельную форму, тк выбор базы в большинстве случаев осуществляется выбором в дереве обьектов сервера. Но для данного батчера это дерево обьектов не нужно.
Кроме того для этой утилитки не предусмотрен выбор каталога со скриптами и сохранение откорректированных скриптов - однако это вы можете доделать сами - это меньше десяти строчек. В остальном утилита представляет собой законченное приложение, прекрасно подходящее для подобных SQL-инсталляций.
Учтите, что при развертывании сборок, вам придется включить в инсталляционный пакет всю среду текущей версии .NET, ибо SQL2005 в боевой версии конечно же будет поддерживать иную версию .NET, чем на вашем девелоперском кампе.
Если же вы попали на эту страничку не для того, чтобы получить готовый скриптер инсталляций, а для того, чтобы посмотреть на технику работы с RichTextBox'ом, то еще больше полезного вы сможете извлечь из нижепубликуемой формы, компонента PE.
В отличии от вышеприведенной формы, допускающей прямое редактирование текста, на этой форме работа с RichTextBox'ом производится в основном мышью. Тексты рассматриваются как гиперссылки, которые надо сразу же открыть (предварительно раззиповав). А форматирование текста тут производится не постфактум, а непосредственно при загрузке текста в RichTextBox.
00001: Public Class More 00002: 00003: Public CurRow As Integer 00004: Dim PRM1 As New SqlClient.SqlParameter 00005: Shared DesignTimeCaption As String = "" 00006: 00007: Private Sub GroupBox1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles GroupBox1.Resize 00008: Dim X As Windows.Forms.GroupBox 00009: X = CType(sender, Windows.Forms.GroupBox) 00010: txComment.Width = X.ClientSize.Width - 20 00011: txURL.Width = X.ClientSize.Width - 71 00012: btUrl.Left = txURL.Left + txURL.Width 00013: btComment.Left = btUrl.Left 00014: txAttach.Width = X.ClientSize.Width - 220 00015: btAttach.Left = txAttach.Left + txAttach.Width 00016: btAttachDir.Left = btAttach.Left + btAttach.Width 00017: btOK.Left = X.ClientSize.Width - 90 00018: ' 00019: txComment.Height = X.ClientSize.Height - 90 00020: btComment.Top = X.ClientSize.Height - 90 00021: lbURl.Top = X.ClientSize.Height - 60 00022: txURL.Top = lbURl.Top 00023: btUrl.Top = lbURl.Top 00024: btOK.Top = X.ClientSize.Height - 30 00025: btAttach.Top = btOK.Top 00026: btAttachDir.Top = btOK.Top 00027: txAttach.Top = btOK.Top 00028: lbAttach.Top = btOK.Top + 5 00029: End Sub 00030: 00031: Private Sub More_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated 00032: txComment.Focus() 00033: End Sub 00034: 00035: Private Sub More_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 00036: 'заголовок берем Ридером еще раз из базы - просто так 00037: SqlConnection1.ConnectionString = CStr(frMain.CurrentConnectionString) 00038: SqlConnection1.Open() 00039: If DesignTimeCaption = "" Then DesignTimeCaption = Me.Text 00040: Me.Text = DesignTimeCaption & " (" & SqlConnection1.DataSource.ToString & "-" & SqlConnection1.Database.ToString & ")" 00041: SqlCommand2.CommandText = "select CreateSignature,CreateDate,Name from PE_Error where i=" & CurRow.ToString 00042: Dim RDR As SqlClient.SqlDataReader = SqlCommand2.ExecuteReader() 00043: RDR.Read() 00044: Call RichAppend(txMore, RDR.GetString(0) & " (" & RDR.GetSqlDateTime(1).ToString & ") :" & vbCrLf, Drawing.FontStyle.Bold) 00045: Call RichAppend(txMore, RDR.GetString(2) & vbCrLf, Drawing.FontStyle.Regular) 00046: RDR.Close() 00047: SqlConnection1.Close() 00048: 'остальное берем в Датасет 00049: PE_CommentTA1.Connection.ConnectionString = CStr(frMain.CurrentConnectionString) 00050: PE_CommentTA1.FillByI(PE1.PE_Comment, CurRow) 00051: Dim j As Integer 00052: For j = 0 To PE1.PE_Comment.Rows.Count - 1 00053: Call RichAppend(txMore, PE1.PE_Comment(j).PrgSignature & " (" & PE1.PE_Comment(j)._Date & ") :" & vbCrLf, Drawing.FontStyle.Bold) 00054: Call RichAppend(txMore, PE1.PE_Comment(j).DirectComment & vbCrLf, Drawing.FontStyle.Regular) 00055: Call RichAppend(txMore, PE1.PE_Comment(j).URLComment & vbCrLf, Drawing.FontStyle.Underline) 00056: Call RichAppend(txMore, PE1.PE_Comment(j).AttachName & vbCrLf, Drawing.FontStyle.Underline) 00057: Next 00058: SqlCommand1.Parameters.Add(PRM1) 00059: End Sub 00060: 00061: Private Sub RichAppend(ByVal Rich As System.Windows.Forms.RichTextBox, ByVal Str1 As String, ByVal FntStyle As System.Drawing.FontStyle) 00062: 'all text entered after the selection is also formatted with the same settings until a setting change is made or a different section of the control's document is selected. 00063: Dim FNT As System.Drawing.Font, FNT1 As System.Drawing.Font 00064: Dim SelFrom As Integer = txMore.TextLength 00065: Dim SelLen As Integer = Str1.Length 00066: txMore.AppendText(Str1) 00067: FNT = txMore.SelectionFont 00068: FNT1 = New Drawing.Font(FNT, FntStyle) 00069: txMore.Select(SelFrom, SelLen) 00070: txMore.SelectionFont = FNT1 00071: End Sub 00072: 00073: Private Sub More_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 00074: If txComment.TextLength > 0 Or txURL.TextLength > 0 Or txAttach.TextLength > 0 Then 00075: Dim X As Integer = MsgBox("Сохранить введенное в базу?", MsgBoxStyle.YesNo) 00076: If X = vbYes Then 00077: Call btOK_Click(Nothing, Nothing) 00078: End If 00079: End If 00080: End Sub 00081: 00082: Private Sub btUrl_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btUrl.Click 00083: txURL.Text = Windows.Forms.Clipboard.GetText 00084: End Sub 00085: 00086: Private Sub btComment_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btComment.Click 00087: txComment.Text &= Windows.Forms.Clipboard.GetText 00088: End Sub 00089: 00090: Private Sub txMore_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles txMore.DoubleClick 00091: Dim Z As System.Windows.Forms.MouseEventArgs = CType(e, Windows.Forms.MouseEventArgs) 00092: Dim PT As System.Drawing.Point = (New System.Drawing.Point(Z.X, Z.Y)) 00093: Dim ClickLineNumber As Integer = txMore.GetLineFromCharIndex(txMore.GetCharIndexFromPosition(PT)) 00094: Dim URL0 As String = txMore.Lines(ClickLineNumber) 00095: Dim URL1 As String = txMore.Lines(ClickLineNumber - 1) 00096: Dim URL As String 00097: If URL0 = "" And URL1 = "" Then 00098: MsgBox("Непонятный баг выделения пустой строки." & vbCrLf & _ 00099: "CharIndexFromPosition=" & txMore.GetCharIndexFromPosition(PT) & vbCrLf & _ 00100: "ClickLineNumber=" & ClickLineNumber & vbCrLf & _ 00101: "Lines(" & ClickLineNumber - 1 & ")=" & txMore.Lines(ClickLineNumber - 1) & vbCrLf & _ 00102: "Lines(" & ClickLineNumber & ")=" & txMore.Lines(ClickLineNumber) & vbCrLf & _ 00103: "Lines(" & ClickLineNumber + 1 & ")=" & txMore.Lines(ClickLineNumber + 1) & vbCrLf, MsgBoxStyle.Information) 00104: Exit Sub 00105: Else 00106: If URL1 = "" And URL0 <> "" Then 00107: URL = URL0 00108: Else 00109: If URL1 <> "" And URL0 = "" Then 00110: URL = URL1 00111: Else 00112: Dim repl1 As Integer = MsgBox("Непонятный баг выделения имени открываемого файла." & vbCrLf & _ 00113: "Для выбора открываемого файла из верхней строки - нажмите YES," & vbCrLf & _ 00114: "нижней стоки - нажмите NO" & vbCrLf & vbCrLf & _ 00115: txMore.Lines(ClickLineNumber - 1) & vbCrLf & _ 00116: txMore.Lines(ClickLineNumber), MsgBoxStyle.YesNo) 00117: If repl1 = vbYes Then 00118: URL = URL1 00119: Else 00120: URL = URL0 00121: End If 00122: End If 00123: End If 00124: End If 00125: If txMore.SelectionFont.Underline Then 00126: If InStr(URL, ".com", CompareMethod.Text) > 0 Or InStr(URL, ".ru", CompareMethod.Text) > 0 Or InStr(URL, ".net", CompareMethod.Text) > 0 Then 00127: System.Diagnostics.Process.Start("C:\Program Files\Internet Explorer\Iexplore.exe", URL) 00128: Else 00129: Dim I As Integer, KeyLine As String, j As Integer 00130: For I = ClickLineNumber To 0 Step -1 00131: j = txMore.GetFirstCharIndexFromLine(I) 00132: txMore.Select(j, txMore.Lines(I).Length - 1) 00133: If txMore.SelectionFont.Bold Then 00134: 'это строка с заголовком 00135: Try 00136: KeyLine = txMore.Lines(I) 00137: Catch ex As Exception 00138: MsgBox("Непонятный баг парсинга заголовка." & vbCrLf & _ 00139: "CharIndexFromPosition=" & txMore.GetCharIndexFromPosition(PT) & vbCrLf & _ 00140: "ClickLineNumber=" & ClickLineNumber & vbCrLf & "FirstCharIndexFromLine=" & j, MsgBoxStyle.Information) 00141: End Try 00142: If KeyLine.Length > 20 Then 00143: Dim pos1 As Integer = InStr(KeyLine, " ") 00144: If pos1 > 0 Then 00145: Dim S As String = Mid(KeyLine, 1, pos1 - 1) 00146: Dim N As String = Mid(KeyLine, pos1 + 2, KeyLine.Length - pos1 - 4) 00147: Dim Y As DateTime 00148: Try 00149: Y = DateTime.Parse(N) 00150: Catch ex As Exception 00151: 'это была не дата а фигня - дальнейшие действия бесполезны 00152: MsgBox("Непонятный баг парсинга заголовка." & vbCrLf & "Запись внесена - <" & S & ">, дата внесения - <" & N & ">." & vbCrLf & _ 00153: "CharIndexFromPosition=" & txMore.GetCharIndexFromPosition(PT) & vbCrLf & _ 00154: "ClickLineNumber=" & ClickLineNumber & vbCrLf & "FirstCharIndexFromLine=" & j, MsgBoxStyle.Information) 00155: Exit Sub 00156: End Try 00157: txMore.Select(ClickLineNumber - 1, txMore.Lines(ClickLineNumber - 1).Length) 00158: txMore.ScrollToCaret() 'почему-то не срабатывает 00159: SqlConnection1.Open() 00160: SqlCommand1.CommandText = "SELECT AttachFile FROM PE_Comment " & _ 00161: "WHERE (ToError = " & CurRow.ToString & _ 00162: ") AND (PrgSignature = '" & S & _ 00163: "') AND (datediff(s,Date, @Date)<1)" 00164: 'разница в дате меньше секунды, тк в консоли даты выводятся округленно 00165: PRM1.ParameterName = "Date" 00166: PRM1.DbType = DbType.DateTime 00167: PRM1.Value = Y 00168: Dim RDR As SqlClient.SqlDataReader = SqlCommand1.ExecuteReader() 00169: If Not RDR.HasRows Then 00170: MsgBox("Непонятный баг отсутствия записи при запросе: " & vbCrLf & SqlCommand1.CommandText & vbCrLf & _ 00171: "@Date=" & Y.ToString, MsgBoxStyle.Information) 00172: End If 00173: If RDR.Read() Then 'читаем только первую запись 00174: Dim K As Integer, L(1000) As Byte 00175: Dim TempFileName As String = System.IO.Path.GetTempPath & URL 00176: Dim OutStream As System.IO.FileStream 00177: Try 00178: OutStream = New System.IO.FileStream(TempFileName, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Write, L.Length) 00179: Catch ex As Exception 00180: MsgBox("Невозможно создать временный файл <" & TempFileName & ">.", MsgBoxStyle.Information) 00181: Exit Sub 00182: End Try 00183: For K = 0 To Integer.MaxValue 00184: Dim M As Integer = CInt(RDR.GetBytes(0, K * L.Length, L, 0, L.Length)) 00185: If M > 0 Then 00186: OutStream.Write(L, 0, M) 00187: Else 00188: Exit For 00189: End If 00190: Next 00191: OutStream.Close() 00192: If System.IO.Path.GetExtension(TempFileName) = ".ZIP" Then 00193: System.Diagnostics.Process.Start("C:\Program Files\Internet Explorer\Iexplore.exe", TempFileName) 00194: Else 00195: Try 00196: System.Diagnostics.Process.Start(TempFileName) 00197: Catch h As System.ComponentModel.Win32Exception 00198: MsgBox("Нет стандартного приложения для чтения файлов такого типа.", MsgBoxStyle.Information) 00199: End Try 00200: End If 00201: End If 00202: RDR.Close() 00203: SqlConnection1.Close() 00204: Exit Sub 00205: End If 00206: End If 00207: End If 00208: Next 00209: End If 00210: End If 00211: End Sub 00212: 00213: Private Sub btAttach_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btAttach.Click 00214: OpenFileDialog1.FileName = "" 00215: OpenFileDialog1.ShowDialog() 00216: If OpenFileDialog1.FileName = "" Then Exit Sub 00217: If FileLen(OpenFileDialog1.FileName) > 10000000 Then 00218: MsgBox("Возможна обработка файлов длиной не более 10000000 байт") 00219: End If 00220: txAttach.Text = System.IO.Path.GetFileName(OpenFileDialog1.FileName) 00221: End Sub 00222: 00223: Private Sub btOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btOK.Click 00224: If txComment.TextLength > 0 Or txURL.TextLength > 0 Or txAttach.TextLength > 0 Then 00225: If txAttach.TextLength > 0 Then 00226: If ZipFile <> "" And FolderBrowserDialog1.SelectedPath <> "" And InStr(txAttach.Text, ".zip", CompareMethod.Text) > 0 Then 00227: Dim X As New System.IO.FileStream(ZipFile, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read, 1000) 00228: Dim Y(CInt(FileLen(ZipFile))) As Byte 00229: X.Read(Y, 0, CInt(FileLen(ZipFile))) 00230: PE_CommentTA1.Insert(CurRow, txURL.Text, txComment.Text, Environment.UserDomainName & "\" & Environment.UserName, Now, Y, txAttach.Text) 00231: Else 00232: Dim X As New System.IO.FileStream(OpenFileDialog1.FileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read, 1000) 00233: Dim Y(CInt(FileLen(OpenFileDialog1.FileName))) As Byte 00234: X.Read(Y, 0, CInt(FileLen(OpenFileDialog1.FileName))) 00235: PE_CommentTA1.Insert(CurRow, txURL.Text, txComment.Text, Environment.UserDomainName & "\" & Environment.UserName, Now, Y, txAttach.Text) 00236: End If 00237: Else 00238: PE_CommentTA1.Insert(CurRow, txURL.Text, txComment.Text, Environment.UserDomainName & "\" & Environment.UserName, Now, Nothing, "") 00239: End If 00240: Call RichAppend(txMore, Environment.UserDomainName & "\" & Environment.UserName & vbCrLf, Drawing.FontStyle.Bold) 00241: Call RichAppend(txMore, txComment.Text & vbCrLf, Drawing.FontStyle.Regular) 00242: Call RichAppend(txMore, txURL.Text & vbCrLf, Drawing.FontStyle.Underline) 00243: Call RichAppend(txMore, txAttach.Text & vbCrLf, Drawing.FontStyle.Underline) 00244: txComment.Text = "" : txURL.Text = "" : txAttach.Text = "" 00245: txMore.ScrollToCaret() 00246: End If 00247: End Sub 00248: 00249: Private Sub СкопироватьToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles СкопироватьToolStripMenuItem.Click 00250: Windows.Forms.Clipboard.SetData(System.Windows.Forms.DataFormats.Rtf, txMore.Rtf) 00251: End Sub 00252: 00253: Private Sub btAttachDir_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btAttachDir.Click 00254: FolderBrowserDialog1.ShowDialog() 00255: If FolderBrowserDialog1.SelectedPath = "" Then Exit Sub 00256: 'Зиповка выполняется асинхронно в другом потоке Шелом 00257: ZipFile = ZipWizard(FolderBrowserDialog1.SelectedPath) 00258: FileSystemWatcher1.Path = System.IO.Path.GetDirectoryName(ZipFile) 00259: FileSystemWatcher1.Filter = System.IO.Path.GetFileName(ZipFile) 00260: FileSystemWatcher1.NotifyFilter = IO.NotifyFilters.LastAccess 00261: Windows.Forms.Application.DoEvents() 00262: 'явный переход в ожидание в принципе здесь не нужен, поток завершится и так 00263: 'но событий CHANGED возникает МНОЖЕСТВО - как же понять какое из них последнее? 00264: 'Dim x As System.IO.WaitForChangedResult = FileSystemWatcher1.WaitForChanged(IO.WatcherChangeTypes.Created, 10000) 00265: End Sub 00266: 00267: Dim ZipFile As String 00268: 00269: 'понять когда ZIP-файл прекратится записыватьcя НЕВОЗМОЖНО и не нужно, запись в базу по кнопке OK 00270: Private Sub FileSystemWatcher1_Changed(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed 00271: txAttach.Text = System.IO.Path.GetFileName(FolderBrowserDialog1.SelectedPath).ToString & ".ZIP" 00272: End Sub 00273: End Class
Текст контролов формы выглядит так:
00001: <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ 00002: Partial Class More 00003: Inherits System.Windows.Forms.Form 00004: 00005: 'Form overrides dispose to clean up the component list. 00006: <System.Diagnostics.DebuggerNonUserCode()> _ 00007: Protected Overrides Sub Dispose(ByVal disposing As Boolean) 00008: If disposing AndAlso components IsNot Nothing Then 00009: components.Dispose() 00010: End If 00011: MyBase.Dispose(disposing) 00012: End Sub 00013: 00014: 'Required by the Windows Form Designer 00015: Private components As System.ComponentModel.IContainer 00016: 00017: 'NOTE: The following procedure is required by the Windows Form Designer 00018: 'It can be modified using the Windows Form Designer. 00019: 'Do not modify it using the code editor. 00020: <System.Diagnostics.DebuggerStepThrough()> _ 00021: Private Sub InitializeComponent() 00022: Me.components = New System.ComponentModel.Container 00023: Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(More)) 00024: Me.SplitContainer1 = New System.Windows.Forms.SplitContainer 00025: Me.Panel1 = New System.Windows.Forms.Panel 00026: Me.txMore = New System.Windows.Forms.RichTextBox 00027: Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components) 00028: Me.СкопироватьToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem 00029: Me.GroupBox1 = New System.Windows.Forms.GroupBox 00030: Me.btAttachDir = New System.Windows.Forms.Button 00031: Me.txAttach = New System.Windows.Forms.TextBox 00032: Me.btOK = New System.Windows.Forms.Button 00033: Me.btAttach = New System.Windows.Forms.Button 00034: Me.lbAttach = New System.Windows.Forms.Label 00035: Me.btComment = New System.Windows.Forms.Button 00036: Me.lbURl = New System.Windows.Forms.Label 00037: Me.btUrl = New System.Windows.Forms.Button 00038: Me.txURL = New System.Windows.Forms.TextBox 00039: Me.txComment = New System.Windows.Forms.RichTextBox 00040: Me.SqlConnection1 = New System.Data.SqlClient.SqlConnection 00041: Me.SqlCommand1 = New System.Data.SqlClient.SqlCommand 00042: Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog 00043: Me.SqlCommand2 = New System.Data.SqlClient.SqlCommand 00044: Me.FolderBrowserDialog1 = New System.Windows.Forms.FolderBrowserDialog 00045: Me.FileSystemWatcher1 = New System.IO.FileSystemWatcher 00046: Me.PE_CommentTA1 = New DS.PETableAdapters.PE_CommentTableAdapter 00047: Me.PE1 = New DS.PE 00048: Me.SplitContainer1.Panel1.SuspendLayout() 00049: Me.SplitContainer1.Panel2.SuspendLayout() 00050: Me.SplitContainer1.SuspendLayout() 00051: Me.Panel1.SuspendLayout() 00052: Me.ContextMenuStrip1.SuspendLayout() 00053: Me.GroupBox1.SuspendLayout() 00054: CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).BeginInit() 00055: CType(Me.PE1, System.ComponentModel.ISupportInitialize).BeginInit() 00056: Me.SuspendLayout() 00057: ' 00058: 'SplitContainer1 00059: ' 00060: Me.SplitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D 00061: Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill 00062: Me.SplitContainer1.Location = New System.Drawing.Point(0, 0) 00063: Me.SplitContainer1.Name = "SplitContainer1" 00064: Me.SplitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal 00065: ' 00066: 'SplitContainer1.Panel1 00067: ' 00068: Me.SplitContainer1.Panel1.Controls.Add(Me.Panel1) 00069: Me.SplitContainer1.Panel1MinSize = 100 00070: ' 00071: 'SplitContainer1.Panel2 00072: ' 00073: Me.SplitContainer1.Panel2.Controls.Add(Me.GroupBox1) 00074: Me.SplitContainer1.Panel2MinSize = 100 00075: Me.SplitContainer1.Size = New System.Drawing.Size(441, 505) 00076: Me.SplitContainer1.SplitterDistance = 307 00077: Me.SplitContainer1.TabIndex = 19 00078: ' 00079: 'Panel1 00080: ' 00081: Me.Panel1.Controls.Add(Me.txMore) 00082: Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill 00083: Me.Panel1.Location = New System.Drawing.Point(0, 0) 00084: Me.Panel1.Name = "Panel1" 00085: Me.Panel1.Size = New System.Drawing.Size(437, 303) 00086: Me.Panel1.TabIndex = 0 00087: ' 00088: 'txMore 00089: ' 00090: Me.txMore.BackColor = System.Drawing.Color.WhiteSmoke 00091: Me.txMore.ContextMenuStrip = Me.ContextMenuStrip1 00092: Me.txMore.Cursor = System.Windows.Forms.Cursors.Default 00093: Me.txMore.Dock = System.Windows.Forms.DockStyle.Fill 00094: Me.txMore.Location = New System.Drawing.Point(0, 0) 00095: Me.txMore.Name = "txMore" 00096: Me.txMore.ReadOnly = True 00097: Me.txMore.Size = New System.Drawing.Size(437, 303) 00098: Me.txMore.TabIndex = 0 00099: Me.txMore.Text = "" 00100: ' 00101: 'ContextMenuStrip1 00102: ' 00103: Me.ContextMenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.СкопироватьToolStripMenuItem}) 00104: Me.ContextMenuStrip1.Name = "ContextMenuStrip1" 00105: Me.ContextMenuStrip1.Size = New System.Drawing.Size(191, 26) 00106: ' 00107: 'СкопироватьToolStripMenuItem 00108: ' 00109: Me.СкопироватьToolStripMenuItem.Name = "СкопироватьToolStripMenuItem" 00110: Me.СкопироватьToolStripMenuItem.Size = New System.Drawing.Size(190, 22) 00111: Me.СкопироватьToolStripMenuItem.Text = "Скопировать в Word" 00112: ' 00113: 'GroupBox1 00114: ' 00115: Me.GroupBox1.Controls.Add(Me.btAttachDir) 00116: Me.GroupBox1.Controls.Add(Me.txAttach) 00117: Me.GroupBox1.Controls.Add(Me.btOK) 00118: Me.GroupBox1.Controls.Add(Me.btAttach) 00119: Me.GroupBox1.Controls.Add(Me.lbAttach) 00120: Me.GroupBox1.Controls.Add(Me.btComment) 00121: Me.GroupBox1.Controls.Add(Me.lbURl) 00122: Me.GroupBox1.Controls.Add(Me.btUrl) 00123: Me.GroupBox1.Controls.Add(Me.txURL) 00124: Me.GroupBox1.Controls.Add(Me.txComment) 00125: Me.GroupBox1.Dock = System.Windows.Forms.DockStyle.Fill 00126: Me.GroupBox1.Location = New System.Drawing.Point(0, 0) 00127: Me.GroupBox1.Name = "GroupBox1" 00128: Me.GroupBox1.Size = New System.Drawing.Size(437, 190) 00129: Me.GroupBox1.TabIndex = 20 00130: Me.GroupBox1.TabStop = False 00131: Me.GroupBox1.Text = "Добавить:" 00132: ' 00133: 'btAttachDir 00134: ' 00135: Me.btAttachDir.Image = Global.PE.My.Resources.Resources.i75 00136: Me.btAttachDir.Location = New System.Drawing.Point(303, 157) 00137: Me.btAttachDir.Name = "btAttachDir" 00138: Me.btAttachDir.Size = New System.Drawing.Size(18, 19) 00139: Me.btAttachDir.TabIndex = 26 00140: Me.btAttachDir.UseVisualStyleBackColor = True 00141: ' 00142: 'txAttach 00143: ' 00144: Me.txAttach.Enabled = False 00145: Me.txAttach.Location = New System.Drawing.Point(90, 157) 00146: Me.txAttach.Name = "txAttach" 00147: Me.txAttach.Size = New System.Drawing.Size(214, 20) 00148: Me.txAttach.TabIndex = 25 00149: ' 00150: 'btOK 00151: ' 00152: Me.btOK.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte)) 00153: Me.btOK.Location = New System.Drawing.Point(349, 157) 00154: Me.btOK.Name = "btOK" 00155: Me.btOK.Size = New System.Drawing.Size(78, 19) 00156: Me.btOK.TabIndex = 24 00157: Me.btOK.Text = "Send" 00158: Me.btOK.UseVisualStyleBackColor = True 00159: ' 00160: 'btAttach 00161: ' 00162: Me.btAttach.Image = Global.PE.My.Resources.Resources.i293 00163: Me.btAttach.Location = New System.Drawing.Point(321, 157) 00164: Me.btAttach.Name = "btAttach" 00165: Me.btAttach.Size = New System.Drawing.Size(18, 19) 00166: Me.btAttach.TabIndex = 23 00167: Me.btAttach.UseVisualStyleBackColor = True 00168: ' 00169: 'lbAttach 00170: ' 00171: Me.lbAttach.AutoSize = True 00172: Me.lbAttach.Location = New System.Drawing.Point(6, 163) 00173: Me.lbAttach.Name = "lbAttach" 00174: Me.lbAttach.Size = New System.Drawing.Size(80, 13) 00175: Me.lbAttach.TabIndex = 22 00176: Me.lbAttach.Text = "Вложить файл" 00177: ' 00178: 'btComment 00179: ' 00180: Me.btComment.Font = New System.Drawing.Font("Microsoft Sans Serif", 6.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte)) 00181: Me.btComment.ForeColor = System.Drawing.SystemColors.ControlText 00182: Me.btComment.Image = Global.PE.My.Resources.Resources.i63 00183: Me.btComment.Location = New System.Drawing.Point(410, 86) 00184: Me.btComment.Name = "btComment" 00185: Me.btComment.Size = New System.Drawing.Size(18, 19) 00186: Me.btComment.TabIndex = 1 00187: Me.btComment.UseVisualStyleBackColor = True 00188: ' 00189: 'lbURl 00190: ' 00191: Me.lbURl.AutoSize = True 00192: Me.lbURl.Location = New System.Drawing.Point(6, 124) 00193: Me.lbURl.Name = "lbURl" 00194: Me.lbURl.Size = New System.Drawing.Size(32, 13) 00195: Me.lbURl.TabIndex = 20 00196: Me.lbURl.Text = "URL:" 00197: ' 00198: 'btUrl 00199: ' 00200: Me.btUrl.Font = New System.Drawing.Font("Microsoft Sans Serif", 6.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte)) 00201: Me.btUrl.ForeColor = System.Drawing.SystemColors.ControlText 00202: Me.btUrl.Image = Global.PE.My.Resources.Resources.i63 00203: Me.btUrl.Location = New System.Drawing.Point(409, 122) 00204: Me.btUrl.Name = "btUrl" 00205: Me.btUrl.Size = New System.Drawing.Size(18, 19) 00206: Me.btUrl.TabIndex = 0 00207: Me.btUrl.UseVisualStyleBackColor = True 00208: ' 00209: 'txURL 00210: ' 00211: Me.txURL.BackColor = System.Drawing.Color.WhiteSmoke 00212: Me.txURL.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, CType(204, Byte)) 00213: Me.txURL.Location = New System.Drawing.Point(42, 122) 00214: Me.txURL.MaxLength = 300 00215: Me.txURL.Name = "txURL" 00216: Me.txURL.Size = New System.Drawing.Size(368, 20) 00217: Me.txURL.TabIndex = 18 00218: ' 00219: 'txComment 00220: ' 00221: Me.txComment.BackColor = System.Drawing.Color.WhiteSmoke 00222: Me.txComment.Location = New System.Drawing.Point(9, 19) 00223: Me.txComment.Name = "txComment" 00224: Me.txComment.Size = New System.Drawing.Size(418, 86) 00225: Me.txComment.TabIndex = 17 00226: Me.txComment.Text = "" 00227: ' 00228: 'SqlConnection1 00229: ' 00230: Me.SqlConnection1.FireInfoMessageEventOnUserErrors = False 00231: ' 00232: 'SqlCommand1 00233: ' 00234: Me.SqlCommand1.Connection = Me.SqlConnection1 00235: ' 00236: 'OpenFileDialog1 00237: ' 00238: Me.OpenFileDialog1.Filter = "Любые (*.*)|*.*|Графика (*.BMP, *.ICO, *.GIF, *.JPG)|*.BMP, *.ICO, *.GIF, *.JPG|T" & _ 00239: "ексты (*.txt)|*.txt|Excel (*.xls)|*.xls" 00240: ' 00241: 'SqlCommand2 00242: ' 00243: Me.SqlCommand2.Connection = Me.SqlConnection1 00244: ' 00245: 'FileSystemWatcher1 00246: ' 00247: Me.FileSystemWatcher1.EnableRaisingEvents = True 00248: Me.FileSystemWatcher1.SynchronizingObject = Me 00249: ' 00250: 'PE_CommentTA1 00251: ' 00252: Me.PE_CommentTA1.ClearBeforeFill = True 00253: ' 00254: 'PE1 00255: ' 00256: Me.PE1.DataSetName = "PE1" 00257: Me.PE1.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema 00258: ' 00259: 'More 00260: ' 00261: Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) 00262: Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font 00263: Me.ClientSize = New System.Drawing.Size(441, 505) 00264: Me.Controls.Add(Me.SplitContainer1) 00265: Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon) 00266: Me.Name = "More" 00267: Me.ShowInTaskbar = False 00268: Me.Text = "Подробные комментарии к текущей ошибке" 00269: Me.SplitContainer1.Panel1.ResumeLayout(False) 00270: Me.SplitContainer1.Panel2.ResumeLayout(False) 00271: Me.SplitContainer1.ResumeLayout(False) 00272: Me.Panel1.ResumeLayout(False) 00273: Me.ContextMenuStrip1.ResumeLayout(False) 00274: Me.GroupBox1.ResumeLayout(False) 00275: Me.GroupBox1.PerformLayout() 00276: CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).EndInit() 00277: CType(Me.PE1, System.ComponentModel.ISupportInitialize).EndInit() 00278: Me.ResumeLayout(False) 00279: 00280: End Sub 00281: Friend WithEvents SplitContainer1 As System.Windows.Forms.SplitContainer 00282: Friend WithEvents Panel1 As System.Windows.Forms.Panel 00283: Friend WithEvents txMore As System.Windows.Forms.RichTextBox 00284: Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox 00285: Friend WithEvents btComment As System.Windows.Forms.Button 00286: Friend WithEvents lbURl As System.Windows.Forms.Label 00287: Friend WithEvents btUrl As System.Windows.Forms.Button 00288: Friend WithEvents txURL As System.Windows.Forms.TextBox 00289: Friend WithEvents txComment As System.Windows.Forms.RichTextBox 00290: Friend WithEvents PE_CommentTA1 As DS.PETableAdapters.PE_CommentTableAdapter 00291: Friend WithEvents PE1 As DS.PE 00292: 00293: Public Sub New(ByVal RowID As Integer) 00294: 00295: ' This call is required by the Windows Form Designer. 00296: InitializeComponent() 00297: 00298: ' Add any initialization after the InitializeComponent() call. 00299: CurRow = RowID 00300: End Sub 00301: Friend WithEvents SqlConnection1 As System.Data.SqlClient.SqlConnection 00302: Friend WithEvents SqlCommand1 As System.Data.SqlClient.SqlCommand 00303: Friend WithEvents btAttach As System.Windows.Forms.Button 00304: Friend WithEvents lbAttach As System.Windows.Forms.Label 00305: Friend WithEvents btOK As System.Windows.Forms.Button 00306: Friend WithEvents txAttach As System.Windows.Forms.TextBox 00307: Friend WithEvents OpenFileDialog1 As System.Windows.Forms.OpenFileDialog 00308: Friend WithEvents SqlCommand2 As System.Data.SqlClient.SqlCommand 00309: Friend WithEvents ContextMenuStrip1 As System.Windows.Forms.ContextMenuStrip 00310: Friend WithEvents СкопироватьToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem 00311: Friend WithEvents btAttachDir As System.Windows.Forms.Button 00312: Friend WithEvents FolderBrowserDialog1 As System.Windows.Forms.FolderBrowserDialog 00313: Friend WithEvents FileSystemWatcher1 As System.IO.FileSystemWatcher 00314: End Class
<SITEMAP> <MVC> <ASP> <NET> <DATA> <KIOSK> <FLEX> <SQL> <NOTES> <LINUX> <MONO> <FREEWARE> <DOCS> <ENG> <CHAT ME> <ABOUT ME> < THANKS ME> |