(MONO) MONO (2010 год)

SNMP-тестер сетевых устройств. GUI-программа на Windows.Forms для Linux.

http://freeware.vb-net.com/Default.aspx?Product_ID=518982c7-8b8a-4f89-9410-9d3504ce0f31 Мне нравится писать всякие Network Application, у меня на сайте выложены десятки различных OpenSource программ для работы в сетях, например Xping - утилита контроля качества связи, Remote SQL execute for PostgreSQL on GSM/GPRS channel with extreme compress and cryptography.

Однако, я обратил внимание, что хотя у меня выложено достаточно много программ для Linux - однако все они выложены в версиях для командной строки, например GoogleTranslate - англо-русский онлайн переводчик.

И я решил хотя бы одну свою сетевую прогу выложить в версии GUI для Linux - заодно показать всем пример GUI для Linux на System.Windows.Forms.


Чтобы понять тему этой странички случайному начинающему программисту или члену секты мазохистов (любителей платежей Биллу Гейтсу) - нужно хотя бы для начала поставить себе Linux - Установка и начальное конфигурирование OpenSuse Linux и хоть чуть-чуть вникнуть в цель существования MONO - Low cost and platform independent ASP.NET - be free with MONO..


Итак, если мой подход написания программ на Visual Basic на System.Windows.Forms для Linux понятен - то давайте разберемся что за прога тут будет описана, и что за слова 'Public', 'Zywall 70' и последовательность цифр '6.1.2.1.1.1.0' (над словом Zywall) - видны на рисунке слева и для чего такая прога может быть нужна в принципе.

SNMP - это протокол опроса сетевых устройств, который сообщает преполезнейшие сведения о работе различных сетевых устройств. Вот для примера что говорит мне дорогая коммерческая прога о работе моих устройств ZyWall 70 и SRW2016 - это не только название устройства, но и масса преполезнейших счетчиков, показывающих направление движения трафика, загруженность каждого интерфейса:

Это конечно большая и сложная прога, которая делалась немаленькой фирмой в течении четырех лет - а моя прога была сделана за пару часов, но тем не менее она тоже полезна, ибо позволяет проверить наличие устройства в сети, опросить его название, прочитать его счетчики. Кроме того, с помощью SMNP можно совершить просто жуткие вещи над кампутером, работающим под уиндауз:

Моя простая прога имеет ровно тот же самый SNMP-движок, что и большая сложная прога, но отличается от большой проги тем, что большая прога получает все классы MIB (чтобы узнать для произвольного случая что находится в той или иной переменной ответа). А в моей проге можно посмотреть то же самое, но только ответ получается просто в виде 16-ричного дампа, а не в виде точно разобранных именованных полей, которые приходят в ответе устройства. И если вы знаете куда смотреть, то увидите там те же самые цифры.

Все те же самые счетчики по идее можно увидеть и в Web-интерфейсе сетевого устройства, только они там разбросаны по вкладкам и работа web-интерфейса требует больших накладных расходов самого устройства (и залогинивания в Web-интерфейс - чего обычно не требуется чтобы просто посмотреть по SNMP основные счетчики сетевого устройства):

Главная же фишка SNMP заключается в том, чтобы в сетевом устройстве был включен Agent SMNP - тогда все эти полезные счетчики можно не только читать, но и устанавливать, например отключить некоторый порт - просто послав команду SNMP SET. Включение агента делается или в Web-интерфейсе сетевого устройства или в его командной строке.

Теперь, познакомившись с общей теорией SNMP - посмотрим как сделана моя SNMP-программа для Linux на System.Windows.Forms.



Поскольку я привык с сервису студии, а возможно потому что у меня на Win-кампутере стоит два огромных экрана, с которыми я привык работать - я изначально сделал прогу под Visual Studio и перенес готовый проект на Linux-машину. Это мои личные пристрастия. Если бы у меня стояли два огромных экрана на машине под Линуском и я бы изначально привык работать без Intellisense - мне бы ничто не помешало сразу создать проект в MonoDevelop. Ну и кроме того, конечно, что визуальный дизайнер Windows.Forms в MonoDevelop не поддерживается, только дизайнер QT4. Поэтому я просто перенес готовый Windows.Forms-проект с Windows-машины в среду Linux.

Далее (последовательно): проект просто открывается, удаляется ссылка не ненужную сборку из виндузни, проверяется тип проекта (Winforms c GUI). Далее проект запускается - однако выясняется что переменная ANSI является ключевым словом MonoDevelop из-за чего компилятор бейсика VBNC пишет ошибку. Переменная переименовывается в ANSI1 - после чего проект стартует под MONO.

Далее я продемонстрировал как MonoDevelop показывает пространство имен MONO-сборок, заменяющих родные ссылки .NET и экспортировал проект в бинарный Linux-формат. Далее я запустил прогу уже не из под MonoDevelop, и непосредственно из командной строки:

Теперь посмотрим OpenSource-код проги. Прога состоит из модуля формирования сокета SNMP (его я взял готовый из документации и просто переписал его с C++ на бейсик):


   1:  Module SNMP
   2:   
   3:      Public Function [Get](ByVal request As String, ByVal IP As Net.IPAddress, ByVal community As String, ByVal MIBstring As String) As Byte()
   4:          Dim Packet As Byte() = New Byte(1023) {}
   5:          Dim MIB As Byte() = New Byte(1023) {}
   6:          Dim SnmpLen As Integer
   7:          Dim CommunityLen As Integer = community.Length
   8:          Dim MIBvals As String() = MIBstring.Split("."c)
   9:          Dim MIBlen As Integer = MIBvals.Length
  10:          Dim cnt As Integer = 0, temp As Integer, i As Integer
  11:          Dim orgMIBlen As Integer = MIBlen
  12:          Dim Pos As Integer = 0
  13:   
  14:          ' Convert the string MIB into a byte array of integer values
  15:          ' Unfortunately, values over 128 require multiple bytes
  16:          ' which also increases the MIB length
  17:          For i = 0 To orgMIBlen - 1
  18:              temp = Convert.ToInt16(MIBvals(i))
  19:              If temp > 127 Then
  20:                  MIB(cnt) = Convert.ToByte(128 + (temp \ 128))
  21:                  MIB(cnt + 1) = Convert.ToByte(temp - ((temp \ 128) * 128))
  22:                  cnt += 2
  23:                  MIBlen += 1
  24:              Else
  25:                  MIB(cnt) = Convert.ToByte(temp)
  26:                  cnt += 1
  27:              End If
  28:          Next
  29:          SnmpLen = 29 + CommunityLen + MIBlen - 1         'Length of entire SNMP Packet
  30:          'The SNMP sequence start
  31:          Packet(Pos) = &H30                          'Sequence start
  32:          Pos += 1
  33:          Packet(Pos) = Convert.ToByte(SnmpLen - 2)   'sequence size
  34:          Pos += 1
  35:          'SNMP version
  36:          Packet(Pos) = &H2                           'Integer type
  37:          Pos += 1
  38:          Packet(Pos) = &H1                           'length
  39:          Pos += 1
  40:          Packet(Pos) = &H0                           'SNMP version 1
  41:          Pos += 1
  42:          'Community name
  43:          Packet(Pos) = &H4                           ' String type
  44:          Pos += 1
  45:          Packet(Pos) = Convert.ToByte(CommunityLen)        'length
  46:          Pos += 1
  47:          'Convert community name to byte array
  48:          Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(community)
  49:          For i = 0 To data.Length - 1
  50:              Packet(Pos) = data(i)
  51:              Pos += 1
  52:          Next
  53:          'Add GetRequest or GetNextRequest value
  54:          If request = "get" Then
  55:              Packet(Pos) = &HA0
  56:              Pos += 1
  57:          Else
  58:              Packet(Pos) = &HA1
  59:              Pos += 1
  60:          End If
  61:   
  62:          Packet(Pos) = Convert.ToByte(20 + MIBlen - 1)   'Size of total MIB
  63:          Pos += 1
  64:          'Request ID
  65:          Packet(Pos) = &H2       'Integer type
  66:          Pos += 1
  67:          Packet(Pos) = &H4       'length
  68:          Pos += 1
  69:          Packet(Pos) = &H0       'SNMP request ID
  70:          Pos += 1
  71:          Packet(Pos) = &H0
  72:          Pos += 1
  73:          Packet(Pos) = &H0
  74:          Pos += 1
  75:          Packet(Pos) = &H1
  76:          Pos += 1
  77:          'Error status
  78:          Packet(Pos) = &H2        'Integer type
  79:          Pos += 1
  80:          Packet(Pos) = &H1        'length
  81:          Pos += 1
  82:          Packet(Pos) = &H0        'SNMP error status
  83:          Pos += 1
  84:          'Error index
  85:          Packet(Pos) = &H2        'Integer type
  86:          Pos += 1
  87:          Packet(Pos) = &H1        'length
  88:          Pos += 1
  89:          Packet(Pos) = &H0        'SNMP error index
  90:          Pos += 1
  91:          'Start of variable bindings
  92:          Packet(Pos) = &H30       'Start of variable bindings sequence
  93:          Pos += 1
  94:          Packet(Pos) = Convert.ToByte(6 + MIBlen - 1)
  95:          Pos += 1
  96:          ' Size of variable binding
  97:          Packet(Pos) = &H30       'Start of first variable bindings sequence
  98:          Pos += 1
  99:          Packet(Pos) = Convert.ToByte(6 + MIBlen - 1 - 2) 'size
 100:          Pos += 1
 101:          Packet(Pos) = &H6
 102:          Pos += 1
 103:          'Object type
 104:          Packet(Pos) = Convert.ToByte(MIBlen - 1)        'length
 105:          Pos += 1
 106:          'Start of MIB
 107:          Packet(Pos) = &H2B
 108:          Pos += 1
 109:          'Place MIB array in Packet
 110:          For i = 2 To MIBlen - 1
 111:              Packet(Pos) = Convert.ToByte(MIB(i))
 112:              Pos += 1
 113:          Next
 114:          Packet(Pos) = &H5           'Null object value
 115:          Pos += 1
 116:          Packet(Pos) = &H0           'Null
 117:          ReDim Preserve Packet(Pos + 1)
 118:          'Send Packet to destination
 119:          Dim sock As New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Dgram, Net.Sockets.ProtocolType.Udp)
 120:          sock.SetSocketOption(Net.Sockets.SocketOptionLevel.Socket, Net.Sockets.SocketOptionName.ReceiveTimeout, 5000)
 121:          '
 122:          Dim iep As New Net.IPEndPoint(IP, 161)
 123:          Dim ep As Net.IPEndPoint = DirectCast(iep, Net.EndPoint)
 124:          sock.SendTo(Packet, SnmpLen, Net.Sockets.SocketFlags.None, iep)
 125:   
 126:          'Receive response from Packet
 127:          Dim OutBuf(1000) As Byte
 128:          Dim recv As Integer = sock.ReceiveFrom(OutBuf, ep)
 129:          ReDim Preserve OutBuf(recv)
 130:          Return OutBuf
 131:   
 132:      End Function
 133:  End Module

Из модуля вывода дампа:


   1:  Module DUMP
   2:   
   3:      Public Function PrintDump(ByVal ByteArray As Byte()) As String
   4:          If ByteArray Is Nothing Then Return ""
   5:          If ByteArray.Length = 0 Then Return " "
   6:          Dim ANSI1 As New System.Text.ASCIIEncoding
   7:          Dim Out As New System.Text.StringBuilder
   8:          For i As Integer = 0 To ByteArray.Length - 1
   9:              Out.Append(String.Format("{0:X2} ", ByteArray(i)))
  10:              If (i Mod 8 = 7) Then
  11:                  Out.Append("    ")
  12:                  Dim Target(7) As Byte
  13:                  For j As Integer = 0 To 7
  14:                      Target(j) = ByteArray(i + j - 7)
  15:                      If Target(j) > 20 Then
  16:                          Out.Append((ANSI1).GetString(Target, j, 1))
  17:                      Else
  18:                          Out.Append(".")
  19:                      End If
  20:                  Next
  21:                  Out.AppendLine()
  22:              End If
  23:          Next
  24:          'допечатка хвостика из последней неполной строки
  25:          Dim Target1(7) As Byte
  26:          For j As Integer = 0 To (ByteArray.Length Mod 8) - 1
  27:              Target1(j) = ByteArray(ByteArray.Length - (ByteArray.Length Mod 8) + j)
  28:          Next
  29:          Out.Append(New String(" ", (8 - (ByteArray.Length Mod 8)) * 3 + 4))
  30:          Out.Append((ANSI1).GetString(Target1))
  31:          Out.AppendLine()
  32:          Return Out.ToString
  33:      End Function
  34:   
  35:  End Module

Из определения GUI-интерфейса:


   1:  Partial Class SNMP_TESTER
   2:      Inherits System.Windows.Forms.Form
   3:   
   4:      'Form overrides dispose to clean up the component list.
   5:      <System.Diagnostics.DebuggerNonUserCode()> _
   6:      Protected Overrides Sub Dispose(ByVal disposing As Boolean)
   7:          Try
   8:              If disposing AndAlso components IsNot Nothing Then
   9:                  components.Dispose()
  10:              End If
  11:          Finally
  12:              MyBase.Dispose(disposing)
  13:          End Try
  14:      End Sub
  15:   
  16:      'Required by the Windows Form Designer
  17:      Private components As System.ComponentModel.IContainer
  18:   
  19:      'NOTE: The following procedure is required by the Windows Form Designer
  20:      'It can be modified using the Windows Form Designer.  
  21:      'Do not modify it using the code editor.
  22:      <System.Diagnostics.DebuggerStepThrough()> _
  23:      Private Sub InitializeComponent()
  24:          Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(SNMP_TESTER))
  25:          Me.btStart = New System.Windows.Forms.Button
  26:          Me.txObjectID = New System.Windows.Forms.TextBox
  27:          Me.txIP = New System.Windows.Forms.TextBox
  28:          Me.txDump = New System.Windows.Forms.TextBox
  29:          Me.Label1 = New System.Windows.Forms.Label
  30:          Me.Label2 = New System.Windows.Forms.Label
  31:          Me.Label3 = New System.Windows.Forms.Label
  32:          Me.SuspendLayout()
  33:          '
  34:          'btStart
  35:          '
  36:          Me.btStart.Location = New System.Drawing.Point(277, 80)
  37:          Me.btStart.Name = "btStart"
  38:          Me.btStart.Size = New System.Drawing.Size(110, 23)
  39:          Me.btStart.TabIndex = 0
  40:          Me.btStart.Text = "GET"
  41:          Me.btStart.UseVisualStyleBackColor = True
  42:          '
  43:          'txObjectID
  44:          '
  45:          Me.txObjectID.BackColor = System.Drawing.Color.WhiteSmoke
  46:          Me.txObjectID.Font = New System.Drawing.Font("Courier New", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
  47:          Me.txObjectID.Location = New System.Drawing.Point(23, 29)
  48:          Me.txObjectID.Name = "txObjectID"
  49:          Me.txObjectID.Size = New System.Drawing.Size(364, 22)
  50:          Me.txObjectID.TabIndex = 1
  51:          Me.txObjectID.Text = "1.3.6.1.2.1.1.1.0"
  52:          '
  53:          'txIP
  54:          '
  55:          Me.txIP.BackColor = System.Drawing.Color.WhiteSmoke
  56:          Me.txIP.Font = New System.Drawing.Font("Courier New", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
  57:          Me.txIP.Location = New System.Drawing.Point(24, 81)
  58:          Me.txIP.Name = "txIP"
  59:          Me.txIP.Size = New System.Drawing.Size(133, 22)
  60:          Me.txIP.TabIndex = 2
  61:          Me.txIP.Text = "192.168.0.100"
  62:          '
  63:          'txDump
  64:          '
  65:          Me.txDump.BackColor = System.Drawing.Color.WhiteSmoke
  66:          Me.txDump.Font = New System.Drawing.Font("Courier New", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
  67:          Me.txDump.Location = New System.Drawing.Point(24, 144)
  68:          Me.txDump.Multiline = True
  69:          Me.txDump.Name = "txDump"
  70:          Me.txDump.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
  71:          Me.txDump.Size = New System.Drawing.Size(363, 194)
  72:          Me.txDump.TabIndex = 3
  73:          '
  74:          'Label1
  75:          '
  76:          Me.Label1.AutoSize = True
  77:          Me.Label1.ForeColor = System.Drawing.SystemColors.ActiveCaption
  78:          Me.Label1.Location = New System.Drawing.Point(21, 13)
  79:          Me.Label1.Name = "Label1"
  80:          Me.Label1.Size = New System.Drawing.Size(52, 13)
  81:          Me.Label1.TabIndex = 4
  82:          Me.Label1.Text = "Object ID"
  83:          '
  84:          'Label2
  85:          '
  86:          Me.Label2.AutoSize = True
  87:          Me.Label2.ForeColor = System.Drawing.SystemColors.ActiveCaption
  88:          Me.Label2.Location = New System.Drawing.Point(20, 65)
  89:          Me.Label2.Name = "Label2"
  90:          Me.Label2.Size = New System.Drawing.Size(57, 13)
  91:          Me.Label2.TabIndex = 5
  92:          Me.Label2.Text = "IP address"
  93:          '
  94:          'Label3
  95:          '
  96:          Me.Label3.AutoSize = True
  97:          Me.Label3.ForeColor = System.Drawing.SystemColors.ActiveCaption
  98:          Me.Label3.Location = New System.Drawing.Point(21, 128)
  99:          Me.Label3.Name = "Label3"
 100:          Me.Label3.Size = New System.Drawing.Size(55, 13)
 101:          Me.Label3.TabIndex = 6
 102:          Me.Label3.Text = "Response"
 103:          '
 104:          'SNMP_TESTER
 105:          '
 106:          Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
 107:          Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
 108:          Me.ClientSize = New System.Drawing.Size(405, 364)
 109:          Me.Controls.Add(Me.Label3)
 110:          Me.Controls.Add(Me.Label2)
 111:          Me.Controls.Add(Me.Label1)
 112:          Me.Controls.Add(Me.txDump)
 113:          Me.Controls.Add(Me.txIP)
 114:          Me.Controls.Add(Me.txObjectID)
 115:          Me.Controls.Add(Me.btStart)
 116:          Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
 117:          Me.Name = "SNMP_TESTER"
 118:          Me.Text = "SNMP_TESTER"
 119:          Me.ResumeLayout(False)
 120:          Me.PerformLayout()
 121:   
 122:      End Sub
 123:      Friend WithEvents btStart As System.Windows.Forms.Button
 124:      Friend WithEvents txObjectID As System.Windows.Forms.TextBox
 125:      Friend WithEvents txIP As System.Windows.Forms.TextBox
 126:      Friend WithEvents txDump As System.Windows.Forms.TextBox
 127:      Friend WithEvents Label1 As System.Windows.Forms.Label
 128:      Friend WithEvents Label2 As System.Windows.Forms.Label
 129:      Friend WithEvents Label3 As System.Windows.Forms.Label
 130:   
 131:  End Class

И из алгоритма GUI-интерфейса (понятно что алгоритм этот можно расширить в любую сторону, например вытащить на форму "прочитать" или "записать" значение SNMP-обьекта):


   1:  Public Class SNMP_TESTER
   2:   
   3:      Dim SnmpResponse As Byte()
   4:   
   5:      Private Sub btStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btStart.Click
   6:          txDump.Text = ""
   7:          Try
   8:              btStart.Enabled = False
   9:              SnmpResponse = SNMP.Get("get", Net.IPAddress.Parse(txIP.Text), "public", txObjectID.Text)
  10:          Catch generatedExceptionName As Net.Sockets.SocketException
  11:              'нет ответа от устройства
  12:              txDump.Text = "No response"
  13:          Catch ex As System.Exception
  14:              'общий баг проги
  15:              txDump.Text = "Error. " & vbCrLf & ex.Message
  16:          Finally
  17:              btStart.Enabled = True
  18:          End Try
  19:          '
  20:          Try
  21:              txDump.Text = PrintDump(SnmpResponse)
  22:          Catch ex As Exception
  23:              txDump.Text = "Print Error. " & vbCrLf & ex.Message
  24:          End Try
  25:   
  26:      End Sub
  27:  End Class

MonoDevelop устроен так же просто, как и Visual Studio - он просто формирует вызов компилятора командной строки VBNC:


vbnc "-out:/home/admin/Documents/SmnpGUI/bin/Debug/SmnpGUI.exe" -nologo -utf8output -debug:full -optionstrict- -optionexplicit+ -optioncompare:binary -optioninfer+ -define:_MYTYPE=\"WindowsForms\" -rootnamespace:SmnpGUI -define:DEBUG=-1 -define:TRACE=-1 -nowarn:42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 -doc:SmnpGUI.xml -main:SmnpGUI.My.MyApplication -target:winexe "-r:/usr/lib/mono/2.0/System.dll" "-r:/usr/lib/mono/2.0/System.Data.dll" "-r:/usr/lib/mono/2.0/System.Drawing.dll" "-r:/usr/lib/mono/2.0/System.Windows.Forms.dll" "-r:/usr/lib/mono/2.0/System.Xml.dll" "-r:/usr/lib/mono/2.0/System.Core.dll" "-r:/usr/lib/mono/2.0/System.Xml.Linq.dll" "-r:/usr/lib/mono/2.0/System.Data.DataSetExtensions.dll" "/home/admin/Documents/SmnpGUI/DUMP.vb" "/home/admin/Documents/SmnpGUI/Form1.vb" "/home/admin/Documents/SmnpGUI/Form1.Designer.vb" "/home/admin/Documents/SmnpGUI/My Project/AssemblyInfo.vb" "/home/admin/Documents/SmnpGUI/My Project/Application.Designer.vb" "/home/admin/Documents/SmnpGUI/My Project/Resources.Designer.vb" "/home/admin/Documents/SmnpGUI/My Project/Settings.Designer.vb" "/home/admin/Documents/SmnpGUI/SNMP.vb" "-resource:/home/admin/Documents/SmnpGUI/Form1.resources,SmnpGUI.SNMP_TESTER.resources" "-resource:/home/admin/Documents/SmnpGUI/My Project/Resources.resources,SmnpGUI.My Project.Resources.resources" -imports:Microsoft.VisualBasic -imports:System -imports:System.Collections -imports:System.Collections.Generic -imports:System.Data -imports:System.Drawing -imports:System.Diagnostics -imports:System.Windows.Forms -imports:System.Linq -imports:System.Xml.Linq
Warning: Option Strict Off will probably fail.
Warning : VBNC2009: the option optioninfer+ was not recognized - ignored
Warning : VBNC2009: the option doc was not recognized - ignored
Assembly 'SmnpGUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' saved successfully to '/home/admin/Documents/SmnpGUI/bin/Debug/SmnpGUI.exe'.
There were 0 errors and 2 warnings.
Compilation successful
Compilation took 00:00:01.8783010

На выходе компилятора получается .NET-байт код (точнее MONO-байт код) SmnpGUI.exe, которой исполняется run-time движком MONO. Есть и другие варианты, когда например байт-код может быть вперемешку, JAVA и MONO - какие-то функции вам нравится использовать из библиотеки .NET, какие-то из JAVA. Это обеспечивается ран-тайм движком IKVM.NET.

Далее мы получим из MONO байт-кода бинарник (com-файл в концепции Windows) командой mkBundle. Обратите внимание, что tаrget-платформа бинарника может быть любая - на момент написания этой заметки кроме X86 MONO поддерживается на процессорных архитектурах s390, s390x (32 and 64 bits), SPARC (32), PowerPC, AMD64, IA64, ARM, MIPS во всевозможнейших операционных системах.


mkbundle -o /home/admin/Debug/SnmpTester /home/admin/Debug/SmnpGUI.exe --deps
OS is: Linux
Sources: 1 Auto-dependencies: True
   embedding: /home/admin/Debug/SmnpGUI.exe
   embedding: /usr/lib/mono/2.0/mscorlib.dll
   embedding: /usr/lib/mono/gac/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
   embedding: /usr/lib/mono/gac/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
   embedding: /usr/lib/mono/gac/System/2.0.0.0__b77a5c561934e089/System.dll
   embedding: /usr/lib/mono/gac/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
   embedding: /usr/lib/mono/gac/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
   embedding: /usr/lib/mono/gac/System.Security/2.0.0.0__b03f5f7f11d50a3a/System.Security.dll
   embedding: /usr/lib/mono/gac/Mono.Security/2.0.0.0__0738eb9f132ed756/Mono.Security.dll
   embedding: /usr/lib/mono/gac/Mono.WebBrowser/0.5.0.0__0738eb9f132ed756/Mono.WebBrowser.dll
   embedding: /usr/lib/mono/gac/System.Data/2.0.0.0__b77a5c561934e089/System.Data.dll
   embedding: /usr/lib/mono/gac/Mono.Data.Tds/2.0.0.0__0738eb9f132ed756/Mono.Data.Tds.dll
   embedding: /usr/lib/mono/gac/System.Transactions/2.0.0.0__b77a5c561934e089/System.Transactions.dll
   embedding: /usr/lib/mono/gac/System.EnterpriseServices/2.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
   embedding: /usr/lib/mono/gac/Mono.Posix/2.0.0.0__0738eb9f132ed756/Mono.Posix.dll
   embedding: /usr/lib/mono/gac/Accessibility/2.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
   embedding: /usr/lib/mono/gac/Microsoft.VisualBasic/8.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
Compiling:
as -o temp.o temp.s 
cc -ggdb -o /home/admin/Debug/SnmpTester -Wall temp.c `pkg-config --cflags --libs mono`  temp.o
Done

Обратите внимание, что компиляция в бинарник байт-кода MONO - это не собственно движок MONO (устанавливаемый как sudo zypper install mono-core и уж никак не интегрированная среда Monodevelop. Платформа бинарной компиляции MONO-кода - это Ассемблер и gcc конкретной процессорной архитектуры, которые устанавливаются отдельными пакетами sudo zypper install binutils и sudo zypper install gcc на целевую машину изготовления бинарника. На выполнение слинкованный бинарник можно запустить непосредственно, а MONO байт-код в режиме интерпритации движком MONO: mono /home/admin/Debug/SnmpGUI.exe. Чтобы посмотреть глазками на байт-код MONO - его можно открыть в MonoDevelop или в текстовом виде monodis /home/admin/Debug/SnmpGUI.exe, а бинарный исполняемый файл можно посмотреть командой readelf /home/admin/Debug/SnmpGUI. Обратите внимание на различие в размерах файлов - если байт-код MONO занимает 19 КилоБайт, то откпомпилированный загрузочный модуль Linux для X86 занимает 11 МегаБайт.

Вы можете распространять свои MONO-проги в виде байт-кода MONO (на виндузне они работают тоже в MONO), можете в бинарном виде для например X86 платформы, а можете в виде загружаемых USB-флешек. Как их делать я описывал здесь - Загрузочные компакты и флешки (bootable LiveCD and bootable USB).

Эту мою прогу вы можете сгрузить в виде байт-кода MONO и в виде Linux-бинарника для платформы X86 отсюда.



//www.vb-net.com/


Comments ( )
Link to this page: //www.vb-net.com/SNMP_Tester/index.htm
< THANKS ME>