当有人向文件服务器上传文件时,服务器向局域网内相应的工作站发送即时消息。哪位朋友有这方面的资料或心得,希望给点提示。

解决方案 »

  1.   

    做一个目录监视程序,监视文件服务器的上传目录目
    当发现有文件增加,则发送即时消息目录监视:
    -------------------------------------------------
    http://dev.csdn.net/article/60/60717.shtm调用Windows的api函数ReadDirectoryChanges监视指定目录中文件
    或者用SHChangeNotifyRegister和SHChangeNotifyDeregister来注册事件SHChangeNotify
    或者调用API函数-FindFirstChangeNotification 、FindCloseChangeNotification、FindNextChangeNotification 和WaitForSingleObject-------------------------------------------------------------------
    http://delphibbs.timeboat.net:8080/keylife/iblog_show.asp?xid=7311在WIN32下用DELPHI侦测目录变化,可用WIN32提供的文件改变通知API来完成。FindFirstChangeNotification, FindNextChangeNotification,FindCloseChangeNotification。
    在应用程序中调用这些函数时,产生一个监控这个变化的句柄,可用WAIT函数集来等待这个变化。这样,当监控程序运行时,可以达到监控文件变化的动作。更进一步,可把此程序做成一个状态区图标(TRAY)来完成监控。Windows在删除、复制、移动、访问文件时并不发送消息,当然截获不到。要截取这些操作过程的唯一办法就是截获API,这又需要你编写Vxd程序了,杀毒软件都是这样作的。你注意一下杀毒软件一般都带有一个vxd程序。光有vxd还不行,还需截获文件API。还有另外一个办法,就是CIH病毒采用的办法,直接跳到系统零层去操作。具体办法如下:
    一、SIDT指令( 将中断描述符表寄存器IDTR--64位宽,16~47Bit存有中断描述符表IDT基地址--的内容存入指定地址单元)不是特权指令,就是说我们可以在Ring3下执行该指令,获得IDT的基地址,从而修改IDT,增加一个中断门安置我们的中断服务,一旦Ring3程序中产生此中断,VMM就会调用此中断服务程序,而此中断服务程序就运行在Ring0下了。这一点与在DOS下非常相似。二、要实现对系统中所有文件I/O操作的实时监视,还要用到另一种关键技-FileHooking,通过挂接一个处理函数,截获所有与文件I/O操作有关的系 统调用。Windows9x使用32位保护模式可安装文件系统(IFS),由可安装文件系统管理器(IFSManager)协调对文件系统和设备的访问,它接收以Win32API函数调用形式向系统发出的文件I/O请求,再将请求转给文件系统驱动程序FSD,由它调用低级别的IOS系统实现最终访问。每个文件I/OAPI调用都有一个特定的FSD函数与之对应,IFSManager负责完成由API到FSD的参数装配工作,在完成文件I/OAPI函数参数的装配之后转相应FSD执行之前,它会调用一个称为FileSystemApiHookFunction的Hooker函数。通过安装自己的Hooker函数,就可以截获系统内所有对文件I/O的API调用,从而实现实时监控。
     
    ------------------------------------------------------
      

  2.   

    顶。
    目录监控有头绪了,但怎样向工作站发送信息呢?因为工作站的机器有的WIN2000,有的是WIN98.
      

  3.   

    最简单的,用winexec调用net send命令
    复杂一点的话,写一个客户端程序,用TCP/IP或者UDP
    具体怎么做,可以去看看局域网聊天程序的代码转贴一个实现net send的代码出处没找到
    ----------------------------
    implement net send?
    主要是要向局域网内的机器发送信息。function NetSend(dest, Source, Msg: string): Longint; overload; 
    type 
      TNetMessageBufferSendFunction = function(servername, msgname, fromname: PWideChar; 
        buf: PWideChar; buflen: Cardinal): Longint;  
      stdcall; 
    var 
      NetMessageBufferSend: TNetMessageBufferSendFunction; 
      SourceWideChar: PWideChar; 
      DestWideChar: PWideChar; 
      MessagetextWideChar: PWideChar; 
      Handle: THandle; 
    begin 
      Handle := LoadLibrary('NETAPI32.DLL'); 
      if Handle = 0 then 
      begin 
        Result := GetLastError; 
        Exit; 
      end; 
        @NetMessageBufferSend := GetProcAddress(Handle, 'NetMessageBufferSend'); 
      if @NetMessageBufferSend = nil then 
      begin 
        Result := GetLastError; 
        Exit; 
      end;   MessagetextWideChar := nil; 
      SourceWideChar      := nil; 
      DestWideChar        := nil;   try 
        GetMem(MessagetextWideChar, Length(Msg) * SizeOf(WideChar) + 1); 
        GetMem(DestWideChar, 20 * SizeOf(WideChar) + 1); 
        StringToWideChar(Msg, MessagetextWideChar, Length(Msg) * SizeOf(WideChar) + 1); 
        StringToWideChar(Dest, DestWideChar, 20 * SizeOf(WideChar) + 1);     if Source = '' then 
          Result := NetMessageBufferSend(nil, DestWideChar, nil, 
            MessagetextWideChar, Length(Msg) * SizeOf(WideChar) + 1) 
        else 
        begin 
          GetMem(SourceWideChar, 20 * SizeOf(WideChar) + 1); 
          StringToWideChar(Source, SourceWideChar, 20 * SizeOf(WideChar) + 1); 
          Result := NetMessageBufferSend(nil, DestWideChar, SourceWideChar, 
            MessagetextWideChar, Length(Msg) * SizeOf(WideChar) + 1); 
          FreeMem(SourceWideChar); 
        end; 
      finally 
        FreeMem(MessagetextWideChar); 
        FreeLibrary(Handle); 
      end; 
    end; function NetSend(Dest, Msg: string): Longint; overload; 
    begin 
      Result := NetSend(Dest, '', Msg); 
    end; function NetSend(Msg: string): Longint; overload; 
    begin 
      Result := NetSend('', '', Msg); 
    end; // Example: procedure TForm1.Button1Click(Sender: TObject); 
    const 
      NERR_BASE = 2100; 
      NERR_NameNotFound = NERR_BASE + 173; 
      NERR_NetworkError = NERR_BASE + 36; 
      NERR_Success = 0; 
    var 
      Res: Longint; 
      sMsg: string; 
    begin 
      Res := NetSend('LoginName', 'Your Message...'); 
      case Res of 
        ERROR_ACCESS_DENIED: sMsg := 'user does not have access to the requested information.'; 
        ERROR_INVALID_PARAMETER: sMsg := 'The specified parameter is invalid.'; 
        ERROR_NOT_SUPPORTED: sMsg := 'This network request is not supported.'; 
        NERR_NameNotFound: sMsg := 'The user name could not be found.'; 
        NERR_NetworkError: sMsg := 'A general failure occurred in the network hardware.'; 
        NERR_Success: sMsg := 'Message sent!'; 
      end; 
      ShowMessage(sMsg); 
    end; 
      

  4.   

    net send只能让WIN2000自动弹出窗口,但98呢?有没有方法使WIN98不安装客户端,同样可以自动弹出消息窗口(前提是不打开Winpopup)。
      

  5.   

    如果一定要写客户端的话,如何在WIN98中实现对消息的接收?
      

  6.   

    --------------------------
    如果一定要写客户端的话,如何在WIN98中实现对消息的接收?
    --------------------------用TCP/IP,UDP,或者NetBIOS,这些都是win98自带的
    主要思路就是用客户端程序侦听某个端口,
    Delphi带了一个聊天程序的Demo,可以去看看
    \Program Files\Borland\Delphi7\Demos\Internet\NetChat
      

  7.   

    我把“发送消息”这块也写好了,调用NetMessageBufferSend实现的。就在自己的机上试着发送信息给自己,但一点反应都没有。
       我的机器:WINXP,开启了alerter,messenger服务,没上网,有网卡。发送地址:127.0.0.1,没开防火墙。
       如果排除我的程序出错,这样的设置是否能够接收到消息?
      

  8.   

    问题基本上解决,感谢 sdzeng(大头鸟) 的热心帮助。