存档

‘日常’ 分类的存档

win7/8/8.1中c#附加程序到任务栏

2015年5月12日 没有评论

远的不说,自从win7开始,当应用程序可以被附加到任务栏后,任务栏就成为各个应用抢占的入口,这里可以比开始菜单更快地启动程序。后来听说微软对OEM厂商有要求,预装软件不能随便pin到任务栏上,哈哈。

今天衣服自己洗就来分享如何附加程序到任务栏上。

大致的流程是先创建一个快捷方式,然后对该快捷方式执行附加命令。附加完成后,可以删除该快捷方式,任务栏图标还是存在的。对于取消是一样的步骤,无非就是步骤不一样而已。当附加成功后,会在用户的Roaming相关目录下自动生成快捷方式,系统会使用该快捷方式,而不是前面创建的快捷方式。

命令就是动作谓词,常见的谓词有run、open等操作,而附加和取消的谓词就是TaskbarPin/TaskbarUnPin,从实际经验来看,谓词是不区分大小写的。代码很简单,看看就明白了。
先申明操作的返回值枚举

public enum FileResult
{
Success,Failed,Exist,NotExist
}

附加到任务栏

public static FileResult PinToTaskBar(string linkPath, bool deleteLink = false)
{
if (!File.Exists(linkPath))
{
// 快捷方式不存在
return FileResult.Failed;
}

string name = System.IO.Path.GetFileName(linkPath);
string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.None)
+”\\AppData\\Roaming\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar\\”;

if (File.Exists(userPath + name))
{
//当pin到任务栏后,该目录下会生成对应的快捷方式。
//通过判断该文件是否存在判断是否已经pin到任务栏
return FileResult.Exist;
}

ProcessStartInfo psi = new ProcessStartInfo(linkPath);

psi.Verb = “TaskbarPin”;
Process.Start(psi);

if (deleteLink)
{
//pin 完后删除快捷方式
File.Delete(linkPath);
}

return FileResult.Success;
}

取消附加到任务栏

public static FileResult UnPinToTaskBar(string linkPath, bool deleteLink = false)
{
if (!File.Exists(linkPath))
{
// 快捷方式不存在
return FileResult.Failed;
}

string name = System.IO.Path.GetFileName(linkPath);
string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.None)
+ “\\AppData\\Roaming\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar\\”;

if (!File.Exists(userPath + name))
{
//当pin到任务栏后,该目录下会生成对应的快捷方式。
//通过判断该文件是否存在判断是否已经pin到任务栏
return FileResult.NotExist;
}

ProcessStartInfo psi = new ProcessStartInfo(linkPath);

psi.Verb = “TaskbarUnPin”;
Process.Start(psi);

if (deleteLink)
{
//pin 完后删除快捷方式
File.Delete(linkPath);
}

return FileResult.Success;
}

完整的代码如下图所示。

pin2TaskBar

 

在执行附加操作的时候,如果任务栏上已经附加了,执行谓词命令就会失败。同理,如果任务栏上没有,执行取消附加也会失败,所以就需要做一个判断,只在必要的时候来做判断。并根据不同的情况返回不同的枚举。

分类: 日常 标签: , ,

c++和c#相互调用dll

2015年5月5日 评论已被关闭

前不久昊问起来如何让c++和c#相互调用dll,后来专门去搜索了下,现在衣服自己洗分享出来,可能对大家有帮助。
首先我们来说c#调用c++编译的dll。这个网上已经很多了,c++里和普通写法一样,设置导出函数等等,例如c++里有一个函数 int cplusplus(int a,int b),那么在C#里,可以先申明:

[DllImport (abc.dll)]
public extern static int cplusplus(int a,int b);

然后就可以像普通的C#函数一样调用了。有几个需要注意的地方,
1、DllImport 后括号里输入c++ 的dll 的文件名,如果该dll不是在系统目录或者环境变量的目录,或者是c#程序的bin目录里,这里就应该输入完整的路径。建议放到c#的bin目录里。
2、函数必须声明为public的,不要忘记了extern关键字,当然static也所必需的。
反过来,c++是如何调用c#的dll呢,例如c#里有一个函数 public int csharp(int a,int b)在类Pipe下,而Pipe类属于ABC命名空间,那么对于c++项目,首先应该设置项目属性,打开公共语言运行时支持,即/clr标记,然后c++项目中添加c#的dll文件引用,接下来,在cpp文件里添加c#对应函数的命名空间 using namespace ABC;最后就是在需要调用的地方,使用托管代码的方式调用:

Pipe ^p = gcnew Pipe();
int a = p.csharp(3,4);

网上有同学提及编译失败,有一种可能是没有添加dll的引用,如果不喜欢添加引用,那么在cpp 文件里,使用 #using “..\Debug\csharp.dll” 也是一样可以的,不过这里就是用using,而非 include关键字,当然绝对路径也是不可少的。

现在c++和c#相互调用dll的方式就算完成了,有的同学对c++调用c#的dll的方式不太认可。为什么呢,因为要用托管代码的方式。其实上面描述的方法,本质上是使用的COM调用来完成的,微软也给出了直接COM调用的示例,喜欢这种方式的同学不妨琢磨下。

分类: C++, 日常 标签: , ,

在控制面板中添加图标

2015年4月17日 没有评论

如果你的机器上安装了Java,那么会在控制面板上出现一个图标,点击图标后会弹出对话框来进行相关的设置。除了Java外,还有显卡、声卡等都是一样一样的。

对于有的应用程序,除了自身的主逻辑外,有时候还需要在控制面板添加入口,方便用户设置。例如一个windows系统服务,如果单独创建一个快捷方式的话,会被众多其它程序淹没在程序列表中。

我们在实现这个功能的时候,有去网上搜索一番,发现几乎全部都是用VC6或者C++ Builder来实现,一来是由于这些开发环境过于久远,在目前最新的win10系统中可能无法得到验证。另外的原因就在于目前还没有驾驭C++,所以自然想着有没有什么好的替代方案。C++的实现方案是使用cpl文件来达到目的,我们有机会单独展开说。

这里我们使用微软新推荐的方式,注册表,方便简单。

首先我们准备一个exe程序,举例叫做 Profile.exe 吧,然后利用工具生成一个GUID,比如叫做{49E28756-FD3A-4977-8758-AAF2BB10997C}好了。

接下来,我们在注册表HKEY_LCOAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace路径下新建一个子键项,名称为刚才我们生成的GUID,给这个项的默认值(Default)赋值,例如Profile。

第三步,在注册表HKEY_CLASSES_ROOT\CLSID下新建一个项,名称为刚生成的GUID,设置其默认值(Default)为Profile,这里建议和上一步设置的文字保持一致。添加字符串键LocalizedString、InfoTip、System.ApplicationName、System.ControlPanel.Category、System.Software.TaskFileUrl,并为它们设置值。LocalizedString是在控制面板里显示的字符,可以使用程序里的资源,例如 @%ProgrameFiles%\Profile.exe,-9 。InfoTip是指在控制面板上鼠标划过对应项时出现的浮动提示内容。System.ApplicationName是程序的调用名称,比如说该值为 Laodaoxia.Profile,那么就可以通过“control.exe /name Laodaoxia.Profile”命令来打开控制面板的这个程序。System.ControlPanel.Category是描述应用程序图标在控制面板里出现的位置,其取值范围为0-11,其中0为在所有项目中显示,1为外观和个性化,2硬件和声音,3为网络和Internet,5为系统和安全,6为时钟、语言和区域,7为轻松使用,8为程序,9为用户账户。其它枚举数值不推荐使用,一般为“1,8”。如果要选择多个,可以用英文逗号分割。

第四步,在注册表HKEY_CLASSES_ROOT\CLSID\{GUID}下新建子键DefaultIcon,设置其默认值(Default)为图标资源,例如%ProgramFiles%\Profile.exe,-2 。这里的{GUID}是第一步创建的GUID,请替换这个占位符。在{GUID}下继续创建 Shell\Open\Command 子键,设置 Command的默认值(Default)为 %ProgramFiles%\Profile.exe。熟悉windows和注册表的同学们一看就知道了,这里就是设置当点击控制面板图标的时候,所运行的具体程序路径,可以带参数哟。

接下来,我们打开控制面板,就可以发现图标已经出现在我们期待的位置上了。

更多信息,可以访问微软MSDN的相关文档

香蕉派(Banana Pi)使用红外IR之安装篇

2015年4月6日 2 条评论

在前面的文章中,衣服自己洗分享了香蕉派(Banana Pi)上关于语音合成的经验,这次就说一说红外线的事情。

香蕉派上已经内置了红外接收装置,硬件是已经有了,这篇文章就来说一下软件的安装。

首先运行

sudo apt-get install lirc

lirc 是一个开源的红外控制软件,安装完成后,修改 /etc/lirc/hardware.conf文件内容,如下

REMOTE=”None”
LOAD_MODULES=true
MODULES=”sunxi-ir”
REMOTE_DRIVER=”devinput”
REMOTE_DEVICE=”/dev/input/event0″
REMOTE_LIRCD_ARGS=””
REMOTE_LIRCD_CONF=””
REMOTE_LIRCMD_CONF=””

上面的内容是专为香蕉派调试出来的,其它的比如说树莓派什么的需要做下调整。

接下来就是拿出你的红外遥控器,香蕉派只能识别出部分的遥控器,我的联想Y450送的遥控器就不支持,反而arduino套件里几块钱的反而可以识别出来。要判断是否可以识别出来,可以运行下面的命令,没有的话就安装下

sudo evtest

接着就按键,如果命令行里有反应,就表示可以识别出来这个红外遥控器。

现在就是准备记录遥控器的命令了,先从lirc那里下载一个通用的版本,

wget http://lirc.sourceforge.net/remotes/generic/NEC.conf

然后呢,就是记录按键,运行命令

irrecord -H devinput -d /dev/input/event0 NEC.conf

这里需要说明下步骤,运行完命令后,首先是提示你按回车继续,然后按照提示,让你先输入按键名称,回车,会提示你按下遥控器对应的按键,接着循环往复只到全部输入完,以回车结束输入。

按键名称不能随便乱写,只能是KEY_1 这样可以识别的,如果要获取可用的名称,可以使用 irrecord -l 命令查看。最后NEC.conf文件里的按键部分,类似下面:

ir

各位同学生成的  0x01000C00000001 这样的字符应该有两列,应该删除后面的一列。后面估计是按键松开的编码。

删除后保存,把文件的内容拷贝到 /etc/lirc/lircd.conf文件里,因为有人说lirc编译代码里是识别固定的文件名。

最后,重启lirc,

sudo /etc/init.d/lirc restart

重启完成后,我们可以来验证是否可以了,运行

irw

按下遥控器上刚才配置的按键,如果出现了内容,就表示配置成功了。截图大致是这样的

irw

到此,香蕉派(Banana Pi)使用红外IR的安装就算完成了,后面的部分就是和程序关联应用了。

 

Linux中访问USB摄像头

2015年3月5日 没有评论

衣服自己洗的香蕉派是基于Lubuntu的arm系统,在前几天刚完成语音合成的技术难题。今天头脑发热,就想看看视频这块。

其实在衣服自己洗的另外一个香蕉派上,已经有一个处理模块了。定时每2分钟,从局域网里的摄像头上获取图片,并上传到yeelink上。当初写这个模块是为了熟悉物联网的概念,所以视频图片并不是从本机获取的。

恰好手头上有一个几年前淘汰的USB摄像头,打算用来练练手。
首先插上USB摄像头,然后运行命令

ls /dev

如果USB摄像头被识别的话,里面应该可以看到video0。

接着查看当前的USB设备

lsusb

我这里运行结果如图所示:

lsusb如红线标记,Z-Star传说是国内比较大的山寨厂商,记录摄像头设备的硬件ID,0ac8:303b,然后访问http://mxhaard.free.fr/spca5xx.html查看spca5xx是否支持你的USB摄像头。

接下来安装camorama,

sudo apt-get install camorama

接下来,可以在远程桌面里访问这个程序,当然香蕉派系统自带的guvcview程序也是可以查看视频的。网上也有下面的方式

sudo apt-get install mplayer

sudo mplayer tv://

不过衣服自己洗用这个方式虽然可以查看视频,不过有一些错误信息。

如果各位同学的摄像头不是免驱动的话,要么就是下载对应的驱动安装,不过最快的就是换个别的型号的摄像头。

分类: 一句话, 日常 标签: , ,

Windows Server禁用SSL 3.0

2015年3月4日 没有评论

今天衣服自己洗在对网站的SSL证书续费的时候,发现网站提供了一个安全工具,顺便就用了一下,发现有个SSL 3的信息泄漏漏洞。

攻击者如何利用此漏洞?

在人为干预 (MITM) 攻击中,攻击者可能使加密的 TLS 会话降低,强制客户端使用 SSL 3.0,然后强制浏览器执行恶意代码。此代码向目标 HTTPS 网站发送许多请求,其中如果存在以前经过身份验证的会话,则会自动发送 Cookie。这是要利用此漏洞所必需的条件。攻击者然后可以截取此 HTTPS 通信,并通过利用 SSL 3.0 中 CBC 分组密码的漏洞,可以对加密通信的某些部分(例如身份验证 Cookie)进行解密。
攻击者可能利用此漏洞执行什么操作?
成功利用此漏洞的攻击者可以对加密通信的某些部分进行解密。
造成此漏洞的原因是什么?
SSL 3.0 中使用的 CBC 加密算法存在漏洞。

在windows server服务器中,基本上都使用的是IIS,而要修复该漏洞的话,需要从注册表入手。修复方式如下:

打开服务器注册表编辑器,找到路径 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols

在下面新建一个 SSL 3.0的项,然后在右边新建一个Dword 格式的键值,名称为Enabled,值为0.

重启服务器即可。

而在微软官方的文档中,Enabled 居然被翻译成中文,导致无法生效。

树莓派/香蕉派语音合成

2015年3月3日 没有评论

自从衣服自己洗入手了香蕉派(banana pi)后,已经过去了很长时间了。
其实这些时间里,一直在解决语音合成的问题。按照当时的初衷是想做一个有点智(dou)能(bi)味道的东西。在olay怀孕期间,做了一个定时任务,每天定时播放胎教音乐,不过现在看起来小红薯似乎对音乐也没有多大兴趣。

然后第二步是打算做天气的定时语音预报,一直比较中意的是科大讯飞的语音合成技术。衣服自己洗本来就对Linux编译特别不熟悉,在他们的开放平台上申请了个appid后,就走上了自我折磨的不归路哇。

由于香蕉派上安装的是Lubuntu系统,硬件配置不算好,所以打算在电脑上把代码编译后再复制到香蕉派上。科大讯飞官方提供的SDK,并没有c#的版本,就考虑用c++编译一个仅仅负责语音合成的程序,然后用c#来写逻辑。Java什么的还是算了吧,看到java一大堆的配置就头疼。

mono安装下来,跑了个命令行似乎没有什么问题,于是开始处理语音合成部分。装了个Ubuntu虚拟机,编译官方的demo后拷贝到香蕉派上,运行失败。突然想起来banana pi是基于arm系统,而虚拟机里的ubuntu是基于x86的。

那么退一步,直接在香蕉派上编译应该就可以了吧。
于是直接远程桌面香蕉派,安装了CodeLite开发环境,上传源码,编译失败,一番搜索发现是要添加 -ldl 选项,但是一看官方的build脚本,是有这个选项的。后来各种尝试后,万万没有想到,应该把 -ldl 放到编译命令的最后面。当然咯,-pthread 也是一样的道理,这里就不多说了。

坑的眼睛都睁不开。

修改了编译脚本后,可以正常编译了,但是运行失败,估计是官方提供的 libmsc.so 库格式不对。
于是发邮件,对方说需要提供appid和交叉编译的名称,于是又网上搜索交叉编译,发现大家用的基本上是arm-linux-gcc,回邮件。一周后,交叉编译提供的 libmsc.so 库发过来,重新引用编译。
运行提示找不到 libmsc.so 库。再次网络搜索,发现Linux系统中对于共享库文件默认是在固定的几个目录里,而不像windows那样,先从程序的运行目录里查找dll文件。添加进去还是不行。接着网络搜索,发现还要设置 export LD_LIBRARY_PATH 为库文件存放的目录,同时还需要sudo ldconfig -v来刷新。

多么纠结的Linux啊~泪流满面。喔,忘记说的是,衣服自己洗还不会C++,为了这事情,又买了C++开发的书来学习,精神可嘉有没有~

运行还是提示找不到libmsc.so文件,官方论坛里也没有有效的答复,最后我放弃了。

今天在论坛里发现官方释放了一个针对树莓派的demo,但是提供的是一个静态库a文件。抱着试一试的想法,上传,编译失败。网上搜索也没有个所以然出来。照葫芦画瓢自己写编译脚本运行还是不行。突然想起来前面的 -ldl 要放到最后面的问题,于是添加到最后。终于编译成功,运行成功。

很是激动有没有,这就意味着困扰了好几个月的问题终于解决了。后面就好说了,获取天气预报,用c#来处理,这个实现,就放到后面的博客里描述吧。

女汉子降临

2015年2月25日 1 条评论

如果要衣服自己洗来评价说2月份最重要的事情,莫过于女汉子的降临。代码写的好,萝莉生的早。

2月4日,农历腊月16,立春,顺产,6斤8两。

妈妈辛苦了,当时我还不在身边,难以想象她一个人是如何害怕和坚强的熬过那几个小时。

对于属相,还有一个故事,现代对于属相有2种标准,一个是按照黄历,每年的立春属于新的属相开始。而另外的一种说法是从初一的零点开始。小萝莉恰好是立春那天出生,但是又没有过农历新年。衣服自己洗还很纠结了一番。

后来发现,那天的立春是从上午的11点58分开始,而小萝莉是早上5点多生的。所以无论是哪一种标准,都是属马,巧妙避免了这种属相的选择尴尬性。

过年的时候,衣服自己洗本还担心她会收到鞭炮的惊吓,结果女汉子是睡的各种舒服,一点都没有收到干扰。在稍微宽慰的时候,又担心她是不是有先天性的听力问题,后来发现有时在关门的时候,她会受到惊吓,看起来应该是可以听到声音的。

小萝莉出生在过年前,怕冬天给冻住了,一个不留神,结果给捂住了,胳膊上一大片伤口,把人都给心疼坏了,大院里的小妹妹恰好是新生儿科的护士,又赶紧抱去医院检查,医生只是担心会引起败血症,好在女汉子体温正常,又能吃能睡,开了百多邦就回来了,一涂抹第二天果然就好了很多。

小妹妹在去找医生检查的时候,由于我们只能站在外面等待,远远的我看着医生胸前的铭牌,豁然就是我高中同班同学的名字,而且从外貌上我一眼就认出来了。一来时间快10年了,我怕认错了。另外一个原因她还是当年我的女神,现在看着心里仍然觉得很腼腆。所以最后我也没有主动打招呼。

回家的这2个星期里,几乎每天晚上都睡不好。从12点就到5、6点钟都是折腾的时候,10分钟左右就要换一次尿布,自己当父母了才知道当初爸妈的辛苦。

最后,衣服自己洗打算给小萝莉的乳名叫做小红薯,哈哈。当初怀孕产检回去的路上,会买个烤红薯吃,小萝莉出生后,也吃了很多红薯稀饭,小红薯,妥妥的。

分类: 日常 标签: ,

Python初试

2015年1月13日 没有评论

工作上最近有遇到一个事情,服务器收集的日志信息里,对于日期格式的字符串描述采用的是yyyy-M-d的方式,而后端逻辑程序对这块的处理的不够(这个让衣服自己洗很是迷惑),但由于跨部门利益关系,问题的解决优先级不够高。

于是,一个折衷的思路就是在后端逻辑处理日志前,先通过某种方式来个预处理。递归遍历目录下的所有子目录和文件,打开文件,正则查找到要处理的日期字符串,替换,然后保存。看起来不太复杂。

由于是Linux服务器,同时也因为一些原因,服务器上也无法安装mono,所以通过c# 写处理程序的方式就行不通。剩下的就分为下面几种思路:

  1. shell 命令
  2. perl/python 脚本
  3. C/C++ 程序

问题就在于我对这些都不会,最开始是想用c++来处理。然后网上搜索了一通资料,对于跨平台的c++,也碰到些问题,例如io.h头文件是没有的,对于正则估计还得用boost之类的,然后后面使用 strncat 这样的函数简直是给弄恶心了。所以在连抄带猜地写完目录遍历后,我就放弃了。Java 程序,我觉得还是算了吧。

我觉得为解决这个事情去学一个语言,成本是不是太高了点,想抱个大腿。找到了@屈屈,他很快就给出了答案,这就是差距。

for i in `ls *.txt`;do mv -f $i `echo $i | sed ‘s/-\([0-9]\)/0\1/g’`;done

虽然不能完全看懂啥意思,不过看起来很绚丽,对不对~多谢屈屈的帮助。

后来网上又下了个Python电子版教程,简单看了下,网上各种搜索和抄袭,最后弄了个Python的脚本,也算是勉强交差吧。

code

import os
import re
import sys

dir = “/Users/mmcer/temp”
if len(sys.argv) > 2:
dir = sys.arg[1]

def check(dir):
for f in os.listdir(dir):
file = os.path.join(dir,f);
if os.path.isdir(file):
check(file)
#pass
elif os.path.isfile(file):
if(f.startswith(“.”)):
#filter Linux system file
pass
else:
print “path is ” + file
think(file)

def think(path):
file = open(path,”r”)
content = file.read()
file.close();

reg = re.compile(“(\d{4})-(\d+)-(\d+)”,re.M)
matches = reg.findall(content)

for match in matches:
year = match[0]
month = match[1]
day = match[2]
old = year + “-” + month + “-” + day

_year = match[0]
_month = match[1]
_day = match[2]

if len(year) == 2:
_year = “20” + year
if(len(month) == 1):
_month = “0” + month
if(len(day) == 1):
_day = “0” + day

newStr = _year +”-” + _month + “-” + _day

content = content.replace(old,newStr)

file = open(path,”w”)
file.write(content)
file.close()

check(dir)

两种思路都提供给对方了,至于如何选择就看人家怎么使用了。

分类: 日常 标签:

pod setup 失败解决

2014年12月11日 没有评论

cocoapods 是 iOS 上不错的包依赖管理软件,在前面的文章里衣服自己洗是有做简单的介绍。

苹果发布了Mac OS X 10.10 后,就安装了新系统和 XCode 6,然后顺便执行了 sudo gem update –system

然后噩梦就来了,这次要创建一个新的项目,写好 podfile 后,结果安装失败。然后网上一搜索,发现 OS X 10.10后有点问题,需要先卸载 cocoapods,然后再重新安装。各种细节和其它诸如Command Line Tools之类的就不展开说了。

安装倒是成功了,可是在执行 pod setup时,总是失败。提示 There was an error reading ‘/Users/mmcer/.cocoapods/repos/master/CocoaPods-version.yml ,然后给了一个官方的URL地址。

按照该地址访问 http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/,使用里面的方法删除本地文件夹

sudo rm -rf ~/.cocoapods/repo/master/
sudo setup

仍然失败,衣服自己洗以为是网络、CDN或者国家防火墙的问题,于是回家后又是各种环境,还是不行。网上是各种搜索,大家的解决方法和上面的几乎是一样的。

后来就闲逛github,在他们的 issue 里发现了居然别人也有相同的问题,并且自己摸索解决了。这里真是要汗颜下自己,没有一早想到这里不说,还懒的自己去摸索。

原因就是曾经的更新导致,具体就是 psych 这个组件,卸载然后安装一个低版本就可以了。github 里是用的2.0.0,但是我用了一个略高的版本发现也是可以的。

sudo gem uninstall psych
sudo gem install psych -v 2.0.0

帖子里还有个人是把所有的gem安装的软件都卸载了然后重装发现也可以解决问题,衣服自己洗觉得太麻烦就没有采用。

之后再重新执行 pod setup 和 pod install 都正常了。浪费了3天时间,对进度还是有很大影响的,不过这个是题外话了。

分类: iOS, 一句话, 日常 标签: , , ,