博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
chrome 插件实现mac地址获取
阅读量:6240 次
发布时间:2019-06-22

本文共 11088 字,大约阅读时间需要 36 分钟。


title: chrome 插件实现mac地址获取 tags:

  • chrome
  • 插件
  • 浏览器mac地址
  • host
  • 全平台 categories: chrome date: 2017-07-25 18:18:53

浏览器无法通过js获取到硬件信息众所周知,ie是也是通过ActiveX来完成的。

由于我们一直使用Chrome,因此考虑开发chrome插件。

普通chrome插件也是无法获取到mac地址等信息的,我们采取和本地通信app的实现。

  1. 准备宿主端,我们称之为host

  2. 准备插件端,我们称之为extension

    如上图所示,我们通过插件端和host进行通信,插件也可以通过授权来访问 指定的页面的document。在进行指定编码格式约定后就可以进行我们的编码了。

    对于chrome的插件开发我们就不说了,可以在网络上抄到一堆。

    插件开发

    manifest

    {      "name": "F6养车PC版安全插件",      "version": "1.0",      "manifest_version": 2,      "description": "使用本插件实现从指定PC登录系统",      "background": {        "scripts": [          "background.js"        ]      },      "icons": {        "128": "icon-128.png"      },      "browser_action": {        "default_icon": "icon-19.png",        "default_title": "F6养车PC版安全插件"      },      "homepage_url": "http://m.f6car.com",      "content_scripts": [        {          "matches": [            "http://*/*"          ],          "js": [            "content.js"          ],          "run_at": "document_end"        }      ],      "externally_connectable": {        "matches": [          "http://*.f6car.com/*",          "http://localhost:9001/*",          "http://127.0.0.1:9001/*",          "http://192.168.1.153:9001/*",          "http://192.168.1.19:9001/*"        ]      },      "permissions": [        "nativeMessaging",        "tabs",        "http://*/*",        "https://*/*"      ]    }复制代码

    content.js

    对应后需要增加content.js 负责和页面dom交互

    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {        console.debug("chrome.runtime.onMessage called");        if (!!request.text) {            console.debug("mac address:%s", request.text);            var macEle = document.getElementById("mac");            if (!!macEle) {                macEle.value = request.text            }        }    });复制代码

    brankground.js

    增加和host通信的background.js

    var port = null;    var hostName = "com.f6car.chrome.safe.echo";    var mac = {};    function connect() {        port = chrome.runtime.connectNative(hostName);        port.onMessage.addListener(onNativeMessage);        port.onDisconnect.addListener(onDisconnected);    }         function onNativeMessage(message) {        console.debug("nativemessage:%s",JSON.stringify(message));        chrome.tabs.query({
    active: true}, function (tabs) { console.debug("tabs:%s",JSON.stringify(tabs)); chrome.tabs.sendMessage(tabs[0].id, message, function (response) { console.debug("baground respone"); }); }); } function onDisconnected() { port = null; } chrome.runtime.onMessageExternal.addListener( function (request, sender, sendResponse) { if (request.requestType === "connect") { if (port === null) { connect(); } } else { if (port === null) { connect(); } else { if (!!mac.text) { sendResponse(mac); } } } });复制代码

    host开发

    权限配置

    windows

    {      "name": "com.f6car.chrome.safe.echo",      "description": "F6养车PC版安全插件HOST",      "path": "f6Safe.exe",      "type": "stdio",      "allowed_origins": [        "chrome-extension://fndijacmgfpgicgknoceclheehanolhc/"      ]    }复制代码

    Mac/Linux

    {      "name": "com.f6car.chrome.safe.echo",      "description": "F6养车PC版安全插件HOST",      "path": "HOST_PATH",      "type": "stdio",      "allowed_origins": [        "chrome-extension://fndijacmgfpgicgknoceclheehanolhc/"      ]    }复制代码

    host编写

    windows

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers static std::string GetMACaddress(void) { IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information for up to 16 NICs DWORD dwBufLen = sizeof(AdapterInfo); // Save the memory size of buffer DWORD dwStatus = GetAdaptersInfo( // Call GetAdapterInfo AdapterInfo, // [out] buffer to receive data &dwBufLen); // [in] size of receive data buffer assert(dwStatus == ERROR_SUCCESS); // Verify return value is valid, no buffer overflow PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;// Contains pointer to current adapter info std::string outMsg = ""; do { char acMAC[32]; sprintf(acMAC, "%02X-%02X-%02X-%02X-%02X-%02X", int (pAdapterInfo->Address[0]), int (pAdapterInfo->Address[1]), int (pAdapterInfo->Address[2]), int (pAdapterInfo->Address[3]), int (pAdapterInfo->Address[4]), int (pAdapterInfo->Address[5])); outMsg.append(acMAC); outMsg.append(","); pAdapterInfo = pAdapterInfo->Next; // Progress through linked list } while(pAdapterInfo); if(outMsg.length()>5){ outMsg = outMsg.substr(0,outMsg.length()-1); } return outMsg; } int main(int argc, _TCHAR* argv[]){ std::string outMsg = "{\"text\":\""+GetMACaddress()+"\"}"; unsigned int outLen = outMsg.length(); char *bOutLen = reinterpret_cast
    (&outLen); std::cout.write(bOutLen, 4); std::cout << outMsg << std::flush; return 0; } ```####      Mac/Linux ####```python #!/usr/bin/env python # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # A simple native messaging host. Shows a Tkinter dialog with incoming messages # that also allows to send message back to the webapp. import Queue import struct import sys import threading try: import Tkinter import tkMessageBox except ImportError: Tkinter = None # On Windows, the default I/O mode is O_TEXT. Set this to O_BINARY # to avoid unwanted modifications of the input/output streams. if sys.platform == "win32": import os, msvcrt msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Helper function that sends a message to the webapp. def send_message(message): # Write message size. sys.stdout.write(struct.pack('I', len(message))) # Write the message itself. sys.stdout.write(message) sys.stdout.flush() # Thread that reads messages from the webapp. def read_thread_func(queue): message_number = 0 while 1: # Read the message length (first 4 bytes). text_length_bytes = sys.stdin.read(4) if len(text_length_bytes) == 0: if queue: queue.put(None) sys.exit(0) # Unpack message length as 4 byte integer. text_length = struct.unpack('i', text_length_bytes)[0] # Read the text (JSON object) of the message. text = sys.stdin.read(text_length).decode('utf-8') if queue: queue.put(text) else: # In headless mode just send an echo message back. send_message('{"echo": %s}' % text) if Tkinter: class NativeMessagingWindow(Tkinter.Frame): def __init__(self, queue): self.queue = queue Tkinter.Frame.__init__(self) self.pack() self.text = Tkinter.Text(self) self.text.grid(row=0, column=0, padx=10, pady=10, columnspan=2) self.text.config(state=Tkinter.DISABLED, height=10, width=40) self.messageContent = Tkinter.StringVar() self.sendEntry = Tkinter.Entry(self, textvariable=self.messageContent) self.sendEntry.grid(row=1, column=0, padx=10, pady=10) self.sendButton = Tkinter.Button(self, text="Send", command=self.onSend) self.sendButton.grid(row=1, column=1, padx=10, pady=10) self.after(100, self.processMessages) def processMessages(self): while not self.queue.empty(): message = self.queue.get_nowait() if message == None: self.quit() return self.log("Received %s" % message) self.after(100, self.processMessages) def onSend(self): text = '{"text": "' + self.messageContent.get() + '"}' self.log('Sending %s' % text) try: send_message(text) except IOError: tkMessageBox.showinfo('Native Messaging Example', 'Failed to send message.') sys.exit(1) def log(self, message): self.text.config(state=Tkinter.NORMAL) self.text.insert(Tkinter.END, message + "\n") self.text.config(state=Tkinter.DISABLED) def Main(): if not Tkinter: send_message('"Tkinter python module wasn\'t found. Running in headless ' + 'mode. Please consider installing Tkinter."') read_thread_func(None) sys.exit(0) queue = Queue.Queue() main_window = NativeMessagingWindow(queue) main_window.master.title('Native Messaging Example') thread = threading.Thread(target=read_thread_func, args=(queue,)) thread.daemon = True thread.start() main_window.mainloop() sys.exit(0) def get_mac_address(): import sys import os mac = None if sys.platform == "win32": for line in os.popen("ipconfig /all"): print line if line.lstrip().startswith("Physical Address"): mac = line.split(":")[1].strip().replace("-", ":") break else: for line in os.popen("/sbin/ifconfig"): if 'Ether' in line or 'ether' in line : mac = line.split()[1].replace(":","-") break return mac def get_json(message): return '{"text": "' +message+ '"}' if __name__ == '__main__': send_message (get_json(get_mac_address()))复制代码

    安装脚本

    windows

    :: Copyright 2014 The Chromium Authors. All rights reserved.    :: Use of this source code is governed by a BSD-style license that can be    :: found in the LICENSE file.         :: Change HKCU to HKLM if you want to install globally.    :: %~dp0 is the directory containing this bat script and ends with a backslash.    REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.f6car.chrome.safe.echo" /ve /t REG_SZ /d "%~dp0com.f6car.chrome.safe.echo-win.json" /f复制代码

    Mac/Linux

    #!/bin/sh    # Copyright 2013 The Chromium Authors. All rights reserved.    # Use of this source code is governed by a BSD-style license that can be    # found in the LICENSE file.         set -e         DIR="$( cd "$( dirname "$0" )" && pwd )"    if [ "$(uname -s)" = "Darwin" ]; then      if [ "$(whoami)" = "root" ]; then        TARGET_DIR="/Library/Google/Chrome/NativeMessagingHosts"      else        TARGET_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"      fi    else      if [ "$(whoami)" = "root" ]; then        TARGET_DIR="/etc/opt/chrome/native-messaging-hosts"      else        TARGET_DIR="$HOME/.config/google-chrome/NativeMessagingHosts"      fi    fi         HOST_NAME=com.f6car.chrome.safe.echo         # Create directory to store native messaging host.    mkdir -p "$TARGET_DIR"         # Copy native messaging host manifest.    sudo cp "$DIR/$HOST_NAME.json" "$TARGET_DIR"         # Update host path in the manifest.    HOST_PATH=$DIR/$HOST_NAME    ESCAPED_HOST_PATH=${HOST_PATH\\/}    sudo sed -i -e "s/HOST_PATH/$ESCAPED_HOST_PATH/" "$TARGET_DIR/$HOST_NAME.json"         # Set permissions for the manifest so that all users can read it.    sudo chmod o+r "$TARGET_DIR/$HOST_NAME.json"         echo "Native messaging host $HOST_NAME has been installed."复制代码

    以上完成代码编写,打包即可

参考资料:

http://blog.csdn.net/zhangjs712/article/details/50913114

https://developer.chrome.com/extensions/crx

http://bbs.360.cn/forum.php?mod=viewthread&tid=15079033 (本人就兼容性问题在360浏览器无法安装)

http://open.se.360.cn/open/extension_dev/overview.html

http://blog.csdn.net/talking12391239/article/details/38498557

具体代码可以查看 码云  http://git.oschina.net/qixiaobo/chromeMacGetter

你可能感兴趣的文章
ICommand in Silverlight
查看>>
复选框、单选按钮、下拉列表的定义
查看>>
webdynpro的select_option示例
查看>>
img src 使用 base64 图片数据
查看>>
MapReduce计算每年最高温度
查看>>
Ruby快速入门
查看>>
UVA 12118 Inspector's Dilemma(连通性,欧拉路径,构造)
查看>>
一台电脑同时运行多个tomcat配置方法
查看>>
让文本框只能输入数字
查看>>
pwnable.kr 之 passcode write up
查看>>
多任务之协程浅谈
查看>>
Qt Creator快捷键
查看>>
idea中lombok的使用
查看>>
网站集成支付宝在线支付
查看>>
mac下安装appium
查看>>
js ---- 函数防抖
查看>>
js call 和 apply
查看>>
CentOS 6.5下Percona Xtrabackup的安装错误解决方案
查看>>
VCS双机+oracle 11gR2+ASM主机名修改
查看>>
转:// LINUX下为ORACLE数据库设置大页--hugepage
查看>>