O snadném zasílání instantních zpráv v intranetu jsme již psali. ASP.NET nám dává možnost přímo v naší aplikaci volat libovolnou systémovou knihovnu poskytující určitou službu. V tomto článku si ukážeme, jak zasílat zprávy po síti prostřednictvím volání služby NetMessageBufferSend, spadající pod Network Management Function dostupné v souboru NetApi32.dll.

Připravíme si formulář pro zadávání textu zprávy a příjemce (jméno nebo IP adresu počítače v síti). Pro manipulaci se systémovými knihovnami potřebujeme importovat namespace System.Runtime.InteropServices (díky kterému pak můžeme pracovat s tzv. unmanaged code, což je jednoduše řečeno kód, za který .net Framework nenese zodpovědnost), vestavěnou službu NetMessageBufferSend si zpřístupníme deklarací statické veřejné external metody (public static extern…).

Abychom toto mohli uskutečnit, musíme pracovat s vlastní třídou – není možné kód zapsat přímo do kódu aspx stránky, ať se nám to líbí nebo ne, v tomto případě musíme buď vytvořit vlastní zkompilované assembly nebo zapsat kód do codebehind. Zde potom před deklarací external metody předřadíme zavedení knihovny NetApi32.dll pomocí atributu DllImport – vlastně tak říkáme, že metoda, kterou deklarujeme, je ve skutečnosti obsažena a deklarována externě v souboru NetApi32.dll.

<%@ Page Language=“C#“ Inherits=“MyDemo“ Codebehind=“MyCodeBehind.aspx.cs“ Src=“MyCodeBehind.aspx.cs“ %>
<html>
<body>
  <h3>Poslat zprávu</h3>
  <div style=“width: 520px“>
  <fieldset>
    <legend>Odeslat na počítač<br /></legend>
    <form runat=“server“>
      Zpráva: <asp:TextBox id=“txtMessage“ size=“40″ maxlength=“255″ runat=“server“/><br />
      Příjemce: <asp:TextBox id=“txtMsgTarget“ size=“20″ maxlength=“255″ runat=“server“/>
      <br /><br />
      <asp:Button Text=“Vymazat“ onclick=“Reset“ runat=“server“ />
      <asp:Button Text=“Odeslat“ onclick=“MessageSend“ runat=“server“ />
    </form>
  </fieldset>
  <asp:Label id=“lblError“ runat=“server“ />
  </div>
</body>
</html>

O tento jednoduchý webový formulář se nám stará kód „v pozadí“, takzvaný codebehind v souboru MyCodeBehind.aspx.cs:

using System;
using System.Text;
using System.Web;
using System.Runtime.InteropServices;
using System.Collections;
using System.ComponentModel;
public class MyDemo : System.Web.UI.Page
{
  protected System.Web.UI.WebControls.TextBox txtMessage; // prvek pro zadání zprávy
  protected System.Web.UI.WebControls.TextBox txtMsgTarget; // prvek pro zadání cíle zprávy
  protected System.Web.UI.WebControls.Label lblError; // prvek pro hlášení výsledku odesílání
  private string ShortUserName()
  {
    string UserNameInfo = User.Identity.Name.Substring(User.Identity.Name.IndexOf(„\\“) + 1,User.Identity.Name.Length – (User.Identity.Name.IndexOf(„\\“) + 1));
    return UserNameInfo; // zde se se získá jméno uživatele, jak se hlásí do sítě (bez názvu domény NT)
  }
  [DllImport(„netapi32.dll“,CharSet=CharSet.Auto,ExactSpelling=true)] // atribut pro zavedení unmanaged code
  public static extern uint NetMessageBufferSend(string servername, string msgname, string fromname, string buf, int len); // deklarace externí metody
  protected void MessageSend (Object sender, EventArgs e)
  {
    uint SendStatus = NetMessageBufferSend(null,txtMsgTarget.Text,ShortUserName(),txtMessage.Text,txtMessage.Text.Length * 2); // zavolat metodu pro poslání zprávy s patřičnými parametry
    switch(SendStatus) // zjistit stav odeslání zprávy
    {
      case 0:
        lblError.Text=“Message was successfully sent!“;
      break;
      case 5:
        lblError.Text=“ERROR: You do not have access to the requested function.“;
      break;
      case 50:
        lblError.Text=“ERROR: This network request is not supported.“;
      break;
      case 53:
        lblError.Text=“ERROR: Bad network path.“;
      break;
      case 87:
        lblError.Text=“ERROR: One of the passed parameters is invalid.“;
      break;
      case 123:
        lblError.Text=“ERROR: Invalid name.“;
      break;
      case 2273:
        lblError.Text=“ERROR: The target name could not be found or is not logged in.“;
      break;
      case 2136:
        lblError.Text=“ERROR: A general failure occurred in the network hardware.“;
      break;
      default:
        lblError.Text=“Unknown error“;
      break;
    }
  }
  protected void Reset (Object sender, EventArgs e)
  { // funkce pro reset (vyčištění) formuláře
    txtMessage.Text=““;
    txtMsgTarget.Text=““;
    lblError.Text=““;
  }
}

Vidíme, že deklarace libovolné metody nebo funkce, kterou využívá systém, je v naší aplikaci velmi snadná. Méně snadné už je získat nějakou dokumentaci k takové službě – některé jsou popsány v MSDN (jako třeba námi použitá NetMessageBufferSend), jiné jsou spíše nedokumentované. Tehdy je třeba různě experimentovat a hledat na internetu, kde se dá. Obdobným hledáním jsem právě našel význam kódů, které jako výsledek předává zde použitá služba NetMessageBufferSend. Vstupní parametry často tvoří nějakou zvláštní datovou strukturu, proto u složitějších volání externích metod je potřeba si v aplikaci tuto strukturu nadeklarovat. V této aplikaci jsme si vystačili s použitím typu uint pro návratovou hodnotu (odpovídá rozsahem typu popisovanému typu DWORD) a běžnými string a int pro předání vstupních hodnot. Všimněte si, že délka zadávané zprávy se násobí 2x – je to proto, že kódování zprávy je ve formátu UNICODE (je totožné s použitým výchozím kódováním UTF-8 ASP.NET aplikací), kde jeden znak zabírá 2 bajty kódu. Pokud bychom chtěli použít pro aplikaci jiné kódování, zprávu by bylo potřeba překonvertovat.

Ukázkovou aplikaci si můžete stáhnout – pokud máte funkční síť Microsoft, můžete zkusit odeslat zprávu na zadané jméno počítače nebo na IP adresu počítače v síti. Pro začátek zkuste zadat jméno nebo IP adresu vlastního počítače, zpráva se doručí vám. Aplikace oznámí, jak odesílání dopadlo.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět