C#人脸识别入门篇-Step By Step人脸识别

引言

如今,基于人脸的技术和话题可以说是炙手可热,基于大数据和人工智能的人脸识别更是突破了我们的想象力的极限,如果应用中不能集成人脸识别,那就太跟不上潮流了。人脸识别是一个算法密集型的项目,如果自行开发,需要很深厚的数学功底和算法底蕴,成本较高,我一个做C#的,自问没有那么高的水平能够写出那么复杂的算法,即使能,我们的算法能和其它公司相比吗。不过好在现在是一个互联网时代,自己开发不行,那么使用其它现成的人脸识别引擎可行吗?答案当然是可行的。

本系列文章就将先从静态图片的人脸检测开始,逐步讲解C#是如何进行人脸识别的。共分为以下四篇

1.人脸识别入门—静态照片人脸检测

2.人脸识别入门—基于视频的人脸检测

3.人脸识别入门—人脸识别初应用

4.人脸识别入门—模拟简单的门禁系统应用

在开始之前,我们先来了解一些人脸识别的集成方式和基础知识,为下面的课程做准备。

选择人脸识别引擎的心路历程

通过搜索引擎,可以大致确定集成人脸识别的可选方式有以下几种

1. 集成WebAPI

目前以百度云,腾讯云为首的互联网公司提供了基于WEBAPI的集成方式,可以通过HTTP的方式提交识别请求,识别结果通过JSON串的方式返回。基于HTTP的方式识别人脸是比较慢的,慢的原因在于IO性能,相对来讲,离线版本的API则能够充分利用本机的机器资源,不用往返于所谓的算法云服务器,直接在本地就能完成人脸识别和标记工作。

2. 集成SDK

以Face++和讯飞语音为例,这些公司即提供了在线识别的方式也提供了基于SDK的本地识别方式。本地识别的优点是速度快,集成度高。而且,作为C#,我们还可以搭建自己的云识别平台。如果采用了WEBAPI的,每一笔请求都需要再经过WEBAPI中转,性能上会大打折扣。

因此,如果我们的项目不需要在互联网上访问,可以供选择的只有本地集成SDK一条路了。

集成成本:能免费最好。

软件的成本包括人力成本和采购成本,在考虑成本的时候,自然会想到,我们使用的引擎是否收费呢?即使收费再便宜,一旦流量上来了,也是一笔不小的开支。在做技术选型的时候,成本是一个必须要考虑的因素。有了成本因素,再搜索时,就会悲剧的发现,在百度排首页的那些人脸识别引擎都不是免费的。那么有没有免费的呢。有,网上搜索,这次使用Google搜索,可以发现,github上有一系列的的人脸识别开源代码,但经过试用,不太理想。

踏破铁鞋无觅处,得来全不费功夫

正在一筹莫展之际,突然今日头条推送了一条消息,“人脸识别技术从此免费!虹软一举颠覆人工智能“视”界”,踏破铁鞋无觅处,得来全不费功夫,这么好的机会,何不试试呢。

PS:由于当时并不了解虹软,就是看中了人脸识别和免费去的,后来重新百度了一下虹软,发现这个公司有点意意思,竟然同时拿下了OPPO和VIVO,SAMSUNG这三大手机巨头的单子,还是有两把刷子的。

下载引擎发现只C++

想到就要做到,于是赶紧打开电脑下载了SDK,吐槽下今日头条,做新闻不放链接太不厚道了。只能百度了,链接在这里http://www.arcsoft.com.cn/ai/arcface.html

可是下载后,傻眼了,不得不说虹软的诚意,这次免费的SDK可真够厚道的,包括了人脸识别,人脸检测,人脸跟踪所有的API。不过美中不足的是,这SDK竟然只有C++版本的,Windows版本不出C#,这虹软有点不近人情啊。不过伤心归伤心,活得还做,没有C#,那我们就拿C++的包裹出C#来用。其实有了C++就等于有了C#,因为C#本身是兼容C++的,可以直接调用C++的库。

基础概念讲解

那么,如何使用C#调用C++的库呢,C#提供了两种技术调用C++的DLL,静态调用(DCOM+)和动态调用(P/Invoke)。我们可以将C或者C++的函数封装成COM组件,在C#中调用时比较方便,但是COM组件需要注册,而且多次注册可能也会导致一些问题,同时在处理C或者C++的类型与COM组件的类型转换的时候也可能有些麻烦,采用动态的方式就是直接用C#调用C或者C++已经写好的动态链接库,这几种方式相对而言,P/Invoke要方便一些。

P/Invoke是什么?

  P/Invoke的全称是Platform Invoke (平台调用) 它实际上是一种函数调用机制,通过P/Invoke我们就可以调用非托管DLL中的函数 ,实际上很多NET基类库中定义的类 型内部部调用了从Kernel32.dll,User32.dll,gdi32.dll等非托管DLL中导出的函数。

看一个最简单的例子

[DllImportAttribute(“user32.dll”, EntryPoint = “SetCursorPos”)]

[return: MarshalAsAttribute(UnmanagedType.Bool)] //可写可不写,定义如何封送返回参数

public static extern bool SetCursorPos(int X, int Y);

3) P/Invoke的过程

关于P/Invoke的过程,我找到了MSDN上的一张图,如下所示。

[clip_image001][1]

在使用P/Invoke调用C/C++方法时,会依次执行以下操作

1 查找包含该函数的非托管DLL

2 将该非托管DLL加载到内存中

3 查找函数在内存中的地址并将其参数按照函数的调用约定压栈

4 将控制权转移给非托管函数

注意:只在第一次调用函数时,才会查找和加载非托管DLL并查找函数在内存中的地址。当非托管函数产生异常时,P/Invoke会将异常传递给托管调用方

看起来很复杂,但使用起来却很简单,只需要在C#中重新声明函数的定义就可以了,然后可以像其它函数一样调用。

但是,这里面最棘手的问题是处理要调用函数的签名,还有最难处理的指针和内存问题。我们需要根据SDK的提供方的函数说明来定义函数的签名。C#的自动内存管理机制让我们几乎忘记了C++中很司空见惯的琐碎细节,如果你以前没有玩过P/Invoke,也没有关系,我会给大家尽可能的讲解这里面需要注意的细节。

工业设计哪家强?键盘史上的12个典范

导语:庞大而不易携带的外接键盘,可能在不久的将来被触摸交互技术取代。不过总有许多款经典产品,让计算机硬件收集发烧友们为之沸腾。好了问题来了,究竟键盘设计哪家强?
一、最广泛使用的两种键盘:QWERT&Dvorak

工业设计哪家强?键盘史上的12个典范

QWERTY键盘,也称全键盘,即第一行开头6个字母是Q、W、E、R、T、Y的键盘布局,也就是现在普遍使用的电脑键盘。其设计初衷是为了减少,当两个位置接近的字母同时按下的时候就会卡死的情况。降低了用户打字速度的QWERT键盘,却因为产生时间较早被用户广泛接受。

继续阅读工业设计哪家强?键盘史上的12个典范

如何养水

俗话说养鱼先养水,那么,什么是养水呢? 什么是适合养鱼的好水——从养水说起俗话说养鱼先养水,那么,什么是养水呢?大家都知道,从水龙头放出来的自来水是不适合直接养鱼的,必须先除氯、增氧,要求高的,还要对水的硬度、PH进行调整。我们通常把进缸前对水的处理称之为“做水”,当然,也可以把做水看作是养水的一个环节。经过除氯、增氧、调整硬度和PH值的水算不算好水呢?从常用的测试指标来看,可以算好水,但这种水有两个缺点:一是不够稳定,二是比较“瘦”。用做好的水养鱼,水质很快就会发生变化,因为它缺乏自净能力;做好的水通常比较干净,几乎没有有害的物质,但同时也缺少对鱼和其它生物有益的的东西。把新鲜的自来水在敞口储水容器中屯放一段时间,对除氯、增氧有很大帮助,但这还不是我们说的养水,真正的养水,必须是在水族箱中,而且是在有鱼的条件下才能进行。
继续阅读如何养水

在阿里云 CentOS 服务器(ECS)上搭建 nginx + mysql + php-fpm 环境

阿里云的云服务器(ECS)可以选择多种操作系统,打算用它运行 Drupal 或者 WordPress ,你最好选择 Linux 系统,这篇文章的演示是基于阿里云的 CentOS 操作系统的服务器。我们在上面搭建一个 nginx + mysql + php-fpm 的环境,这就是常说的 LNMP 。我们不过多解释什么是什么,而是着重讲流程与方法,想了解具体的细节,去搜索下吧:)这个手册是在阿里云上测试的,不过应该也适用于其它使用 CentOS 系统的服务器。

 

远程控制你的服务器

远程控制 Linux 类型的系统的服务器,比如 CentOS 系统的服务器,一般不像 Windows 服务器那样,使用图形界面的远程控制。我们需要使用命令行工具,远程连接到服务器,然后使用命令去控制服务器。Windows 用户可以使用 Putty ,Mac 用户可以使用系统自带的终端工具。然后用 ssh 命令,连接到你的服务器。像这样:

ssh root@218.244.147.196
@ 左边的 root 是连接时使用的用户的名字,@ 右边的数字是你的服务器的 IP 地址。这行命令的意思就是,使用 root 用户,登录到 218.244.147.196 这台服务器上。回车以后,会提示你输入 root 用户的密码(这个密码阿里云会发送到你手机上)。

安装 Nginx

想在 CentOS 系统上安装 Nginx ,你得先去添加一个资源库,像这样:

vim /etc/yum.repos.d/nginx.repo
使用 vim 命令去打开 /etc/yum.repos.d/nginx.repo ,如果 nginx.repo 不存在,就会去创建一个这样的文件,打开以后按一下小 i 键,进入编辑模式,然后复制粘贴下面这几行代码,完成以后按 esc 键退出,再输入 :wq (保存并退出)

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
完成以后,我们就可以使用 yum 命令去安装 nginx 了,像这样:

yum install nginx
安装好以后测试一下 nginx 服务:

service nginx status
应该会返回:

nginx is stopped (nginx 已停止)
再测试一下 nginx 的配置文件:

nginx -t
应该会返回:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
… syntax is ok,… test is successful,说明配置文件没问题,同时这个结果里你可以找到 nginx 的配置文件 nginx.conf 所在的位置。

操纵 nginx 服务

操纵服务,可以使用使用 service 命令,它可以启动(start),重启(restart),或停止服务(stop),比如要启动 nginx 服务:

service nginx start
服务启动以后,你就可以在浏览器上使用服务器的 IP 地址,或者指向这个地址的域名访问服务器指定的目录了。你会看到类似下面的这些文字。

Welcome to nginx! If you see this page, the nginx web server is successfully installed and working. Further configuration is required. For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com. Thank you for using nginx.

配置 nginx 虚拟主机

安装完 nginx 以后,第一件想到的事应该就是去创建虚拟主机,虚拟主机允许我们在同一台服务器上运行多个网站,我们可以为不同的域名绑定不同的目录,访问这个域名的时候,会打开对应目录里面的东西。之前介绍过为 Apache 服务器创建虚拟主机,下面来看一下为 nginx 配置虚拟主机。先进入到 nginx 配置文件目录:

cd /etc/nginx/conf.d
复制这个目录里的 default.conf ,复制以后的名字可以使用你的虚拟主机名字。比如创建一个 nginx.ninghao.net 的虚拟主机。复制文件可以使用 cp 命令,像这样:

cp default.conf nginx.ninghao.net.conf
再去编辑一下这个复制以后的配置文件,可以使用 vim 命令:

vim nginx.ninghao.net.conf
你会看到像这样的代码:

server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log   /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

}
server_name 就是主机名,也就是跟这个虚拟主机绑定在一块儿的域名,我事先把 nginx.ninghao.net 指向了服务器,这个虚拟主机就是为它准备的,所以,server_name 后面的东西就是 nginx.ninghao.net 。紧接着 server_name 下面可以是一个 root,就是这个虚拟主机的根目录,也就是网站所在的目录。比如我们要把 nginx.ninghao.net 这个网站的文件放在 /home/www/nginx.ninghao.net 下面,那么这个 root 就是这个路径。

然后去掉 location / 里面的 root 这行代码。再在 index 后面加上一种索引文件名,也就是默认打开的文件,这里要加上一个 index.php ,这样访问 nginx.ninghao.net 就可以直接打开 root 目录下面的 index.php 了。稍后我们再去安装 php 。修改之后,看起来像这样:

server {
listen 80;
server_name nginx.ninghao.net;
root /home/www/nginx.ninghao.net;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;

location / {
index index.php index.html index.htm;
}

}
这个配置文件先修改到这,稍后,我们再回来继续修改一下它。保存一下,按 esc ,输入 :wp(保存并退出)。现在虚拟主机应该就可以使用了。主机的域名是 nginx.ninghao.net,访问它的时候,打开的是 /home/www/nginx.ninghao.net 这个目录里面的东西,你可以在这个目录下放点东西。

重启 nginx 或者重新加载 nginx 可以让配置文件生效。

service nginx reload
现在,打开浏览器,输入你为虚拟主机设置的域名,看看是否能打开你指定的目录里的东西。

配置 php-fpm

要让 nginx 能够执行 php 文件,需要去安装一下 php-fpm,它直接包含在了 CentOS 资源库里,所以直接使用 yum 命令可以安装它:

yum install php-fpm
完成以后,可以检查一下 php-fpm 的运行状态,使用 service 命令:

service php-fpm status
返回:

php-fpm is stopped(php-fpm 已停止)
启动 php-fpm 同样可以使用 service 命令:

service php-fpm start
让 nginx 可以执行 php

现在我们应该就可以让 nginx 去执行 php 了。不过你需要修改一下 nginx 的配置文件,之前我们在配置虚拟主机的时候,创建了一个 nginx.ninghao.net.conf 的配置文件,需要去修改下 nginx 的这个配置文件,才能去执行 php 。使用 vim 命令去编辑它:

vim /etc/nginx/conf.d/nginx.ninghao.net.conf
注意你的配置文件不一定叫 nginx.ninghao.net.conf,应该是你自己命名的配置文件。打开以后,找到下面这段字样的代码:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ .php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}
这是 nginx 默认给我们的用来执行 php 的配置,从 location 开始取消注释,会让这个配置生效,然后我们还得简单去修改一下:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ .php$ {
    #   root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
注意 root 那里仍然是被注释掉的,还有 SCRIPT_FILENAME 后面修改了一下,把 /scripts 换成了 $document_root 。保存并退出。然后重新启动 nginx:

service nginx restart
测试是否可以执行 php

现在,我们已经安装了 php-fpm,并修改了 nginx 的配置文件让它可以去执行 php,下面,我们得去测试一下,可以使用 php 的 phpinfo(); 函数,方法是在你的虚拟主机根目录下面,创建一个 php 文件,命名为 phpinfo.php,然后在这个文件里输入:

<?php phpinfo(); ?>
保存文件并退出。在浏览器里打开刚才创建的这个 php 文件。我这里应该是 http://nginx.ninghao.net/phpinfo.php。打开以后,你应该能看到像下面这样的界面,如果能,说明 nginx 已经可以执行 php 了。

QQ20140322-4

为系统添加资源库

前面我们使用 yum 命令去安装了一些东西,用起来很简单,yum + 要安装的东西 + install。它其实是一个资源包的管理工具,用它安装东西的时候,会检查这个东西所依赖的其它的东西,在安装的同时,也会去安装这些被依赖的东西。CentOS 本身带了一些资源库,但并不是所有的东西都在这些资源库里,所以,我们可以给系统手工的添加一些资源库,这样使用 yum 命令,就可以很方便的去安装在资源库里的东西了。

在这里可以找到可用的资源库:http://iuscommunity.org/pages/Repos.html ,你要根据自己的系统的版本去下载对应的资源库,然后安装在系统里面。查看系统的版本可以这样做:

cat /etc/redhat-release
我这里使用的是 CentOS 系统,所以返回了:

CentOS release 6.3 (Final)
说明我用的是 CentOS 6 ,并且是 64 位的,打开上面的资源库地址,找到 Release Packages ,然后找到 CentOS 6 这个区域下面的链接,我们用这个 epel 资源库。打开这个地址以后,复制 Packages 下面的链接 epel-release-6-5.noarch 。然后回到我们连接到服务器的终端工具,Windows 用户应该用的是 putty 。用 cd 命令进入到一个目录里面,比如用户的根目录,可以这样:

cd ~
然后使用 wget 命令,把刚才复制的链接里的资源库下载下来:

wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/6/x86_64/epel-release-6-5.noarch.rpm
用 ls 命令可以查看一下当前这个目录下面的东西,你应该可以看到 epel-release-6-5.noarch.rpm(也或者是你选择要下载的资源库)。下载好以后,去安装一下:

rpm -ivh epel-release-6-5.noarch.rpm
查看一下系统里面的资源库:

yum repolist
你会看到 epel 这个资源库,它就是我们刚才安装的。系统里的资源库地址是在:/etc/yum.repos.d,在这里,你同样可以找到 epel.repo。这样我们就可以使用 yum 命令去安装更多的东西了。

安装 mysql

mysql 可以管理网站用到的数据库,WordPress 和 Drupal 也都支持 mysql 数据库。所以我们的 Web 运行环境里,需要安装一个 mysql 。之前我们已经添加了资源库,所以可以直接使用 yum 命令去安装  mysql :

yum install mysql-server
安装完成后,使用 service 命令启动 mysql 服务:

service mysqld start
然后我们需要简单配置一下 mysql ,默认安装以后 mysql 的 root 用户是没有密码的,对于生产环境来说,这肯定是不行的,另外还有一些安全相关的设置,可以使用下面这行命令去配置一下,它是一个向导,问你一些问题,你要给出答案,比如是否要设置 root 用户的密码, 密码是什么等等。

mysql_secure_installation
Enter current password for root (enter for none):
解释:输入当前 root 用户密码,默认为空,直接回车。
Set root password? [Y/n]  y
解释:要设置 root 密码吗?输入 y 表示愿意。
Remove anonymous users? [Y/n]  y
解释:要移除掉匿名用户吗?输入 y 表示愿意。
Disallow root login remotely? [Y/n]  y
解释:不想让 root 远程登陆吗?输入 y 表示愿意。
Remove test database and access to it? [Y/n]  y
解释:要去掉 test 数据库吗?输入 y 表示愿意。
Reload privilege tables now? [Y/n]  y
解释:想要重新加载权限吗?输入 y 表示愿意。

安装 php 扩展

现在,我们有了可以提供 web 服务的 nginx ,并且安装了 php-fpm ,配置了 nginx 可以让它去执行 php ,也安装了数据库管理系统。不过在运行真正的网站的时候,我们还需要为 php 安装一些额外的扩展,比如 处理 mysql 数据库的 mysql 扩展,缓存功能的 apc 扩展,处理图像的 gd 扩展等等。安装它们同样可以使用 yum 命令。

yum install php-pecl-apc php-mysql php-gd php-mcrypt php-pear php-mbstring php-xmlrpc php-dom
上面安装了一些 php 的扩展,如果你发现在安装网站的时候提示需要安装其它的扩展,同样可以使用 yum 命令去安装。安装完成以后,需要重启一下 php-fpm :

service php-fpm restart
目录与文件的权限问题

网站上面有些目录或文件需要有写入权限,这样你得为这些目录和文件分配合适的权限,一般可以把它们的拥有者设置成 php 和 nginx 使用的用户,默认 nginx 的用户就是 nginx ,而 php-fpm 使用的用户默认是 apache。我们可以把它们改成一个统一的用户,可以修改 php-fpm 的用户为 nginx 。你可以使用下面的命令去查看一下 nginx 和 php-fpm 所使用的用户名:

ps aux|grep php
ps aux|grep nginx
修改所使用的用户,可以通过使用 nginx 和 php-fpm 的配置文件,nginx 的配置文件是:  /etc/nginx/nginx.conf ,php-fpm 的配置文件是:/etc/php-fpm.conf,还有在 /etc/php-fpm.d/* 这个目录里的所有文件都是 php-fpm 的配置文件。默认这个目录里有一个 www.conf ,你可以编辑这个文件来修改 php-fpm 所使用的用户名称。使用 vim 命令:

vim /etc/php-fpm.d/www.conf
打开文件以后你可以搜索下关键词 user 或 apache,输入 :/user 或 :/apache ,会搜索到结果,按小 n 可以继续向下查找,按大 N 可以向上查找。直到你看到:

user = apache
把它修改成:

user=nginx
esc 退出,再输入 :wq ,重启下 php-fpm,这样我们的 nginx 服务器还有 php-fpm 会使用同一个用户:nginx,你可以把要可以有写入权限的目录与文件的拥有者修改成 nginx 就行了。可以使用 chown 命令:

chown -R nginx 目录名/文件名
总结

好来,现在我们就已经拥有一台 LNMP 环境的服务器了。这个操作手册里提供到的相关配置,还有很多可以优化一下,比如 nginx 的配置文件,可以针对 Drupal 来做一些优化。在后续的文章里面,我会再详细的去解释一下这些配置文件的使用。

超级奢侈的码农享受

沉浸式电脑椅,帝王的选择。只要30万。

Emperor系列的一体工作游戏站其实早在CES2009已经展出过,200是它最新的一代。 官网介绍说,这是终极电脑工作站解决方案,具备触摸板,空气过滤系统,电动皮椅,3X27寸显示屏,光疗系统,超猛音频系统。安卓操控。售价只要30万(起),强烈期望土豪晒单,或者值得买众测也行。

一把舒适的椅子陪我们寂寞

一桌在手,天下我有

想象一下码农们在这台桌子上左右开弓的样子,就像是操控人生的上帝有米有,开启多个工作模式,完全不会精分,关爱自己家的码农,送给他一张未来会更加辛勤工作的桌子。

ios inHouse 发布应用

一、明确几个概念

1、企业版IDP: 即iOS Development Enterprise Program。注意是$299/Year那种,并不是$99/Year的那种

2、In House:是指企业内发布,仅限企业内部人员使用。

二、In-House 特点:

1、不能发布到AppleStore进行销售

2、不需要Apple评审  

3、可以使用任何一支的私有API   

4、可以安装到任何苹果设备上,无需任何签名和认证

5、用户安装只要一个ipa文件,无需证书和签名文件

三、证书的生成过程

1、生成开发和发布证书(cer 文件),和$99账号一样

2、创建App ID,和$99账号一样

3、创建开发mobileprovision文件,和$99账号一样

4、创建发布(in-house)mobileprovision文件,这个如下图和$99账号不同。AdHoc的发布方式和$99是一样的,这里我们选择的In House

5、把刚刚生成的证书和签名文件都安装后,就可以开始我们的发布了。

四、In-House打包

简单过程:Product–>Archive–>(Validate、Submit、Export) Export–>Save for Enterprise Deployment 点击Next,选择对应的企业证书后点击Export 即可成功。(Xcode 6以下ipa 和 plist 同时生成,Xcode6以上 只生成ipa,可copy之前的plist 修改即可)。 

五、企业网页服务器分发

1、按照三、四 步骤 创建ipa 和 plist ,把打包的ipa 放到服务器上,ios设备通过访问网址,即可安装

2、创建web页面 ( 注意:ios7 plist 之前的版本用http,但ios7之后必须使用https)

<!DOCTYPE html>  
    <html>  
    <head>  
      <meta http-equiv="Content-Type" content="text/html; charset=gb2312">  
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />   
      <title>Install Geoloqi</title>  
      <style type="text/css">  
        body {  
          background: url(bkg.png) repeat #c5ccd4;  
          font-family: Helvetica, arial, sans-serif;  
        }  
        .congrats {  
          font-size: 16pt;  
          padding: 6px;  
          text-align: center;  
        }  
        .step {  
          background: white;  
          border: 1px #ccc solid;  
          border-radius: 14px;  
          padding: 4px 10px;  
          margin: 10px 0;  
        }  
        .instructions {  
          font-size: 10pt;  
        }  
        .arrow {  
          font-size: 15pt;  
        }  
        table {  
          width: 100%;  
        }  
      </style>  
    </head>  
    <body>  
       
    <div class="congrats">点击下面图标下载 XXX-App</div>  
       
    <div class="step">  
      <table><tr>  
        <td class="instructions">安装IOS<br />XXX-App</td>  
        <td width="24" class="arrow"></td>  
        <td width="72" class="imagelink">  
          <a href="itms-services://?action=download-manifest&url=https://www.xxx.com/TestInHouse/raw/master/xxx-app.plist">  
            <img src="icon.png" height="72" width="72" />  
           </a>  
        </td>  
      </tr></table>  
<table><tr>  
        <td class="instructions">安装Android<br />作业盒子XXX-App</td>  
        <td width="24" class="arrow"></td>  
        <td width="72" class="imagelink">  
          <a href="http://www.xxx.com/xxx.apk">  
            <img src="icon.png" height="72" width="72" />  
           </a>  
        </td>  
      </tr></table>  
    </div>  
    <script>
function isWeiXin(){
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
return true;
}else{
return false;
}
} 
if (isWeiXin()) {
  alert("请用浏览器打开!");
}
  </script>
    </body>  
    </html>

3、部署和测试 在手机上输入指定的网址,即可实现安装。

plist 文件如下:

plist 外站链接可选择: https://git.oschina.net,, 通过新建项目–>点+ 填入文件名–>把plist文件拷贝到内容区–>提交 即可.

遇到问题参考:

1、http://blog.csdn.net/zhaoxy_thu/article/details/17277527

2、http://stackoverflow.com/questions/20276907/enterprise-app-deployment-doesnt-work-on-ios-7-1/22767699#22767699

3、https://laoyur.com/?p=414

4、http://blog.csdn.net/zhaoxy_thu/article/details/21133399

5、http://www.2cto.com/kf/201312/264286.html

6、http://stackoverflow.com/questions/20276907/enterprise-app-deployment-doesnt-work-on-ios-7-1/22367111#22367111

7、http://www.cnblogs.com/zzy0471/p/3658572.html

Discuz的2003 cannot connect错误的一种解决方法

今天早上,无缘故的出现Discuz论坛无法连接的黄页,黄页的内容是discuz 2003 notconnect.

从表面上看是由于数据库无法连接导致的,但是查看了数据库的mysql服务,是正常启动的,无论是外部还是内部,都是可以连接数据库的.找了很多方法都没有办法定位原因,当然也没有办法解决.

突然间想到SELINUX,搜索了一下,发现SELINUX的确有可能会导致一些服务出现异常,

搜索了一下,网上有比较多的解决方法.一种是直接把SELINUX关闭.

一、查看SELinux状态命令:

1、/usr/sbin/sestatus -v      ##如果SELinux status参数为enabled即为开启状态
SELinux status:                 enabled

2、getenforce                 ##也可以用这个命令检查

二、关闭SELinux方法:

1、临时关闭(不用重启机器):

代码如下:

setenforce 0 #设置SELinux 成为permissive模式
#setenforce 1 设置SELinux 成为enforcing模式

2、修改配置文件需要重启机器:

修改/etc/selinux/config 文件

将SELINUX=enforcing改为SELINUX=disabled

重启机器即可.

另一种办法没有那么激进,添加SELINUX允许DB的远程访问.

修改apache远程访问数据库的布尔值

setsebool httpd_can_network_connect_db 1

什么是SELINUX

SELinux在linux中是保护系统的重要工具,它可以最大限度的保护系统的安全。也许有的人在使用过程中尝试着关闭过此工具,但是当考虑到要架设服务器的话,那就得重视它了。

假设我们希望允许远程匿名访问 Web 服务器,我们必须通过防火墙打开端口。然而,这意味着恶意人员可以尝试利用安全漏洞以及,如果他们损坏 Web 服务器进程,获得 apache 用户和 apache 组的权限来强行进入系统。懂点安全知识的人就知道很危险了,用户 / 组具有 document root ( /var/www/html )等的读取权限以及 /tmp 、/var/tmp 所有人均可写的任何其他文件 / 目录的写入权限。

SELinux 是一组可确定哪个进程能访问哪些文件、目录、端口等的安全规则。每个文件、进程、目录和

端口都具有专门的安全标签,称为 SELinux 上下文。上下文只是一个名称, SELinux 策略使用它来确定

某个进程是否能访问文件、目录或端口。默认情况下,该策略不允许任何交互,因此明确的规则授予访

问权限。如果没有允许规则,则不允许访问。

总之,SELinux 的目标之一是保护用户数据免受已泄漏的系统服务的威胁

SELinux 模式

为了进行故障排除,我们可以临时禁用 SELinux 保护,使用 SELinux 模式。

强制模式, SELinux 主动拒绝访问尝试读取类型上下文为 tmp_t 的文件的 Web 服务器。在强制

模式中, SELinux 不仅记录而且提供保护。

许可模式通常用于对问题进行故障排除。在许可模式中,即使没有明确规则, SELinux 也允许所有交

互,并且记录所有被拒绝的交互。此模式可以用于确定您是否有 SELinux 问题。无需重新引导即可从

强制模式转为许可模式,或再从许可模式转回强制模式。

禁用模式将完全禁用 SELinux 。您必须重新引导才能彻底禁用 SELinux ,或者从禁用模式

转为强制模式或许可模式。

装修清单

装修预算清单

辅料

  • 电线
  • 油漆
  • 水管
  • 水泥,黄沙

主材

  • 瓷砖
  • 地板
  • 马桶
  • 水槽
  • 台盆
  • 吊顶
  • 油烟气灶
  • 室内门

人工

  • 水电
  • 泥工
  • 木工
  • 油漆

家具

  • 柜子门
  • 电视柜,卧室柜子

五金

  • 卫生间五件套
  • 厨房五件套
  • 门栓
  • 门锁
  • 衣柜五金套件

家居用品

  • 沙发
  • 窗帘
  • 地毯