客户端数据上报的简单实现

发布到外网的安装包和客户端程序,经常需要向后台上报一些数据。实现数据上报的方法有很多,其中最简单的方法是,用IE静默打开一个带有查询字符串的URL。这样,只要在apache上部署一个简单的脚本,就能统计数据上报了。

先看下安装包中数据上报的实现,nsis代码如下:

ExecShell "open" "iexplore.exe" "http://127.0.0.1" SW_HIDE

这个脚本对应到win32的API,是ShellExecute。奇怪的是,nsis脚本在安装包上运行的很好,IE能够静默打开,而到了客户端上,用ShellExecute并设置了SW_HIDE,总是不能隐藏。

接着我在网上找到了用CreateProcess打开IE的方法.如下代码展示了从注册表中读取IE的路径,然后用CreateProcess隐藏打开的方法。注意CreateProcess的第二个参数,url的前面要带上open。

STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));

if (!CreateProcess(szIEPath, TEXT("open http://127.0.0.1"), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
     return -1;
}

IE的路径可由如下的GetIEPath获得:

BOOL GetIEPath(LPTSTR lpszPath, int nLen)
{
     BOOL bSuccess = FALSE;
     do
     {
          HKEY hKey = NULL;
          DWORD dwSizeOfPath = 0;
          if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
               TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE"),
               0,
               KEY_READ,
               &hKey))
          {
               break;
          }

          if (ERROR_SUCCESS != RegQueryValueEx(hKey, TEXT(""), NULL, NULL, NULL, &dwSizeOfPath))
          {
               break;
          }

          if (dwSizeOfPath >= nLen)
          {
               break;
          }
          if (ERROR_SUCCESS != RegQueryValueEx(hKey, TEXT(""), NULL, NULL, (LPBYTE)lpszPath, &dwSizeOfPath))
          {
               break;
          }
          lpszPath[dwSizeOfPath + 1] = TEXT(‘\0‘);
          bSuccess = TRUE;
     } while(FALSE);
     return bSuccess;
}

写了这么多代码,现在问题解决了么?我在自己的机器上测试一切正常!

可是...

到了安装IE11的电脑上,nsis脚本的ExecShell和客户端的CreateProcess,打开的IE都展示在用户的面前,我们总不能让用户知道我们在收集数据吧:)

最终,找到了一种更简单的方法,只要调用两个win32接口即可。这样也不需要创建额外的IE进程了。

HINTERNET hInternet1 = InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL);
if (hInternet1)
{
     HINTERNET hInternet2 = InternetOpenUrl(hInternet1,szOpenUrlAddr, NULL, NULL,INTERNET_FLAG_NO_CACHE_WRITE,NULL);
     InternetCloseHandle(hInternet1);
     if (hInternet2)
     {
          InternetCloseHandle(hInternet2);
     }
}

这样实现,我们上报数据,从任务管理器里也不留痕迹,而且代码更短!

把这段代码移植到NSIS插件中,nsis脚本也能够优雅的上报数据了:)

时间: 2024-10-13 06:47:14

客户端数据上报的简单实现的相关文章

struts封装客户端数据到Action

1.在Action中定义简单数据类型的属性 给Action定义简单类型的属性,封装客户端请求的数据 简单类型:String,基本类型和对应的引用类型 只要保证客户端请求的参数名称和Action的属性名称一样. 2.在Action中定义javabean对象封装客户端数据 2.1定义实体类 public class Users { private String uname; private String upwd; private Integer type; public String getUna

【干货】如何通过OPC自定义接口来实现客户端数据的读取?

上篇博文分享了我的知识库,被好多人关注,受宠若惊.今天我把我在项目中封装的OPC自定义接口的程序分享一下.下面将会简单简单介绍下OPC DA客户端数据访问,以及搭配整个系统的运行环境. OPC(OLE for Process Control)其实就是一套标准,我对这套标准理解不多,使用过程中就把它理解一套协议或者规范,主要用于工控领域.OPC中有很多规范,我主要使用OPC DA规范来进行数据的读写操作.还有其他规范,比如OPC UA.OPC HDA等.如果你做的是OPC Server开发查下这方

蚂蚁金服分布式链路跟踪组件 SOFATracer 数据上报机制和源码分析 | 剖析

2019新春支付宝红包技术大揭秘在线峰会将于03-07日开始,点击这里报名届时即可参与大牛互动. SOFAScalable Open Financial Architecture 是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践.SOFATracer 是一个用于分布式系统调用跟踪的组件,通过统一的 TraceId 将调用链路中的各种网络调用情况以日志的方式记录下来,以达到透视化网络调用的目的,这些链路数据可用于故障的快速发现,服务

Linux input系统数据上报流程【转】

转自:https://segmentfault.com/a/1190000017255939 作为鸡生蛋系列文章,这里主要关注Linux input系统,主要为触摸事件上报流程. 读该文章最好有对linux驱动的入门知识.其实当你自己去分析了input系统后,再分析别的就相对很轻松了,linux里好多套路都差不多的. 本文例子以ft6236.c驱动为例, 当然你也可以用goodix或者别的触摸来分析.但是分析基于的内核版本用4.19.6(我写这篇文档时最新稳定版)(https://git.ker

干货 | 快速实现数据导入及简单DCS的实现

干货 | 快速实现数据导入及简单DCS的实现 原创:?赵琦?京东云开发者社区??4月18日 对于多数用户而言,在利用云计算的大数据服务时首先要面临的一个问题就是如何将已有存量数据快捷的导入到大数据仓库中.本文将演示如何基于京东云数据计算服务平台,简单.快速地将数据导入数据计算服务. 我们通常说的大数据平台主要包括三部分:数据相关的产品和技术.数据资产.数据管理.京东云数据计算服务(Data Computing Service,简称:DCS)是一个全托管.低使用成本的云上数据仓库服务.通过数据工厂

网络编程 实现 客户端与服务器端的简单通信

六,代码演示实现客户端与服务器端的简单通信 代码中所使用的 IP号码,必须是本机自己的IP号码 (自行查询:cmd---ipconfig/all ) 1.[客户端向服务器端 发送一个整型数据,服务器端进行接收] (1)先写服务器端 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java

第九章 用多线程来读取epoll模型下的客户端数据

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include

ECMall的MySQL数据调用的简单方法

很多ecmall开发者会问,怎么使用Ecmall的mysql类库进行数据调用.从原理上来讲Ecmall的数据调用是以数据模块+模块类库的方式进行mysql数据调用的,所有数据模块都存储在includesmodels 目录下,这些调用对于初学者来讲是比较复杂的,例如商品的数据调用函数,不能用在店铺的数据调用上,每个数据表都有自己的函数自己的类库和少量的公共类库.因此初学者来讲,调用mysql数据很困难. 现在讲解一个简单的调用方法能满足95%以上的mysql数据调用请求.足够对ecmall进行二次

使用IMP导出数据备份并简单FTP实现异地存储

使用IMP导出数据备份并简单FTP实现异地存储 简介情况: 一共3个服务器 21 14 130 21 生产服务器 14 测试服务器(备份1) 130 备份服务器(备份2) 21上做简单导出数据库备份 ---–autobackup.bat-----每天00:00运行 备份 del d:\ncdatabackup\dmp\xxpc_*.dmp del d:\ncdatabackup\log\xxpc_*.log exp ncjxpc/****** file=d:\ncdatabackup\dmp\x