2013-05-27 123 views
1

我已经提出了一个应用程序来记录当前PC用户访问的所有网站。这不是为了恶意使用。我正在为我的员工监控软件制作此功能,该软件将根据适当的法律获得许可。网站访客(被访问网址)记录器应用程序

关于主要观点,每当我从任何浏览器(如IE)获取URL时。我只获取所有打开的标签的URL。我无法获得任何选项卡处理的IE7 +,因为我无法维护一个标签列表,我已经记录了同一个标签页的URL。 下面是我的代码(就以注释代码首先看了一眼):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.IO; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

namespace WebsiteLoggerConsole 
{ 
    public class WebLogger 
    { 
     [DllImport("user32.dll")] 
     static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint  lpdwProcessId); 
     [DllImport("user32.dll", SetLastError = true)] 
     private static extern IntPtr FindWindowEx(IntPtr hwndParent, 
                IntPtr hwndChildAfter, 
                string lpszClass, 
                string lpszWindow); 

     System.Threading.Timer log; 
     public void StartLoggin() 
     { 
      try 
      { 
       TimerCallback logcallback = new TimerCallback(LogTick); 
       log = new System.Threading.Timer(logcallback, null, 0, 2000); 
      } 
      catch (Exception ex) 
      { 
       Console.ForegroundColor = ConsoleColor.Red; 
       Console.WriteLine(ex.Message); 
      } 
     } 

     public void StopLogging() 
     { 
      try 
      { 
       log.Dispose(); 
      } 
      catch (Exception ex) 
      { 
       Console.ForegroundColor = ConsoleColor.Red; 
       Console.WriteLine(ex.Message); 
      } 
     } 

     public void LogTick(Object stateInfo) 
     { 
      CreateLog(); 
     } 

     void CreateLog() 
     { 
      try 
      { 
       SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows(); 
       string filename; 

       foreach (SHDocVw.InternetExplorer ie in shellWindows) 
       { 
        filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); 
        if (filename.Equals("iexplore")) 
        { 
         int val = ie.HWND; 
         IntPtr hwnd = new IntPtr(val); 
         IntPtr uihwnd = GetDirectUIHWND(hwnd); 
         string ddd = (ie.LocationURL) + " :::: " + (uihwnd.ToString()); 
         Console.WriteLine(ddd); 
        } 
       } 

       //SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows(); 
       //string filename; 

       //foreach (SHDocVw.InternetExplorer ie in shellWindows) 
       //{ 
       // filename =  Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); 
       // if (filename.Equals("iexplore")) 
       // { 
       //  int val = ie.HWND; 
       //  IntPtr hwnd = new IntPtr(val); 
       //  IntPtr uihwnd = GetDirectUIHWND(hwnd); 
       //  IntPtr tabhwnd = GetDirectUIHWND(uihwnd); 
       //  string ddd = (ie.LocationURL) + " :::: " +  (tabhwnd.ToString()); 
       //  Console.WriteLine(ddd); 
       // } 
       //} 

       //Process[] processlist = Process.GetProcesses(); 
       //foreach (Process theprocess in processlist) 
       //{ 
       // if (theprocess.ProcessName == "iexplore") 
       // { 
       //  Console.WriteLine("Process: {0}, ID: {1}, Handle: {3}, Window  name: {2}", 
       //   theprocess.ProcessName, theprocess.Id,  theprocess.MainWindowTitle, theprocess.SessionId.ToString() 
       //  ); 
       // } 
       //} 
      } 
      catch (Exception ex) 
      { 
       Console.ForegroundColor = ConsoleColor.Red; 
       Console.WriteLine(ex.Message); 
      } 
     } 

     private static IntPtr GetDirectUIHWND(IntPtr ieFrame) 
     { 
      // try IE 9 first: 
      IntPtr intptr = FindWindowEx(ieFrame, IntPtr.Zero, "WorkerW", null); 
      if (intptr == IntPtr.Zero) 
      { 
       // IE8 and IE7 
       intptr = FindWindowEx(ieFrame, IntPtr.Zero, "CommandBarClass", null); 
      } 
      intptr = FindWindowEx(intptr, IntPtr.Zero, "ReBarWindow32", null); 
      //intptr = FindWindowEx(intptr, IntPtr.Zero, "TabBandClass", null); 
      //intptr = FindWindowEx(intptr, IntPtr.Zero, "DirectUIHWND", null); 
      return intptr; 
     } 
    } 
} 
+0

请看注释代码,这样你会得到一个想法。 –

回答

1

我提供了这方面的解决方案:How to write a standalone URL logger for Windows?

在那里,我用Java的,但你可以通过使用C#这样做。我几乎可以肯定,C#有很多好的libpcap包装器。

有一个名为pcapDotNet的项目,您可以使用它。

调整一个例子:

using System; 
using System.Collections.Generic; 
using PcapDotNet.Core; 
using PcapDotNet.Packets; 
using PcapDotNet.Packets.IpV4; 
using PcapDotNet.Packets.Transport; 

namespace InterpretingThePackets 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Retrieve the device list from the local machine 
      IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine; 

      if (allDevices.Count == 0) 
      { 
       Console.WriteLine("No interfaces found! Make sure WinPcap is installed."); 
       return; 
      } 

      // Print the list 
      for (int i = 0; i != allDevices.Count; ++i) 
      { 
       LivePacketDevice device = allDevices[i]; 
       Console.Write((i + 1) + ". " + device.Name); 
       if (device.Description != null) 
        Console.WriteLine(" (" + device.Description + ")"); 
       else 
        Console.WriteLine(" (No description available)"); 
      } 

      int deviceIndex = 0; 
      do 
      { 
       Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):"); 
       string deviceIndexString = Console.ReadLine(); 
       if (!int.TryParse(deviceIndexString, out deviceIndex) || 
        deviceIndex < 1 || deviceIndex > allDevices.Count) 
       { 
        deviceIndex = 0; 
       } 
      } while (deviceIndex == 0); 

      // Take the selected adapter 
      PacketDevice selectedDevice = allDevices[deviceIndex - 1]; 

      // Open the device 
      using (PacketCommunicator communicator = 
       selectedDevice.Open(65536,         // portion of the packet to capture 
                      // 65536 guarantees that the whole packet will be captured on all the link layers 
            PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode 
            1000))         // read timeout 
      { 
       // Check the link layer. We support only Ethernet for simplicity. 
       if (communicator.DataLink.Kind != DataLinkKind.Ethernet) 
       { 
        Console.WriteLine("This program works only on Ethernet networks."); 
        return; 
       } 

       // Compile the filter 
       using (BerkeleyPacketFilter filter = communicator.CreateFilter("ip and tcp")) 
       { 
        // Set the filter 
        communicator.SetFilter(filter); 
       } 

       Console.WriteLine("Listening on " + selectedDevice.Description + "..."); 

       // start the capture 
       communicator.ReceivePackets(0, PacketHandler); 
      } 
     } 

     // Callback function invoked by libpcap for every incoming packet 
     private static void PacketHandler(Packet packet) 
     { 
      // print timestamp and length of the packet 
      Console.WriteLine(packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") + " length:" + packet.Length); 

      IpV4Datagram ip = packet.Ethernet.IpV4; 

      //Do your magic here using HttpRequestDatagram 
     } 
    } 
}