使用WSL的两平台互访问

linux下

在ubuntu上,使用

cat /etc/resolv.conf | grep nameserver | cut -d' ' -f2

能得出宿主的IP,这和在windows的命令行中ipconfig看到的一致。

如果你ping 172.28.64.1,如果是通的就不用看本文了。如果不通,就要在windows防火墙中添加入站规则。

windows下

有两种办法,建议使用命令行(并且是管理员权限下)。

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -InterfaceAlias "vEthernet (WSL)"  -Action Allow

如果你执行时权限不够,要确认你的登陆是否为管理员。

一般宿主都是可以ping到linux上。所以,当执行上面命令成功后,到linux上ping一下那个网站,应该是通的了。

到此,完全可以把数据库等主要占资源的软件部署在windows这边了。

从github上查到的示例:

PS C:\WINDOWS\system32> $myIp = (Ubuntu1804 run "cat /etc/resolv.conf | grep nameserver | cut -d' ' -f2")

PS C:\WINDOWS\system32> $myIp

172.21.0.1

PS C:\WINDOWS\system32>  New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -LocalAddress $myIp -Action Allow

go与qt的新酒老瓶

前言

只所以说是新酒老瓶而不是新瓶老酒是有用意的。

因为QT是器,老瓶,出来时配合着C++的。而如今go来势凶凶,自然英雄所见略同。

两大开源神器,跨平台开发,终将双剑合璧了,让你如虎添翼。

过程记录如下

安装QT

→参考指导:

https://www.cnblogs.com/haijian/p/12417129.html

本人使用/usr/local/qt为QTDIR。5.12.10

安装go

→参考指导:

https://blog.csdn.net/icanx/article/details/91438450

→配置go env国内源

liteide源码编译安装

→参考指导:

https://www.cnblogs.com/7explore-share/p/5838281.html?utm_source=debugrun&utm_medium=referral

出现了模板路径报错,于是使用tarena环境,但是root账户,先安装两个包,再改脚本后,编译方成功。

https://www.cnblogs.com/liaojiafa/p/12798025.html

实在是经典解说:

→针对windows平台

在此时需要安装mingw64做为前提,不然liteide就是水土不服的。必要时关闭360吧!

mingw64实是难搞,换了几个工具,如mingw installation manager,最后用mingw-w64-install.exe
启动后选择版本,posix和seh,这就生成了安装目录。
在安装过程中,把此前下载的源码包压缩包“mingw-w64-v8.0.0.zip”重新命名为“x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z”,放置在默认的目录中“x86_64-8.1.0-posix-seh-rt_v6-rev0”
最后,把安装的路径
C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin
放到系统环境变量中。万事大吉。gcc,g++一应具全,随处可用。

GO111MODULE在windows上是没有auto可设置的,即便你使用liteide设置了,但go env中实际还是当它为on。

所以,系统底层仍设置为on,GOPATH目录内的源码编译成功,无论是否有go.mod。但要是GOPATH目录外的拥有go.mod文件(这是通过go mod init src生成的)可以编译成功。

当设置为off时,同时也得让GOPROXY为空,这时GOPATH和有go.mod的外部目录都可在命令行编译成功。所以,建议你还是使用命令行吧,因为,同一代码在命令行和liteide中结果不同,并且,保持on状态,保持代码不在GOPATH中。相信,go的发展也是会弃掉它。

→针对linux平台

GO111MODULE可以被liteide设置成auto.

这样设置的好处是模糊使用GOPATH(任何设置都OK)。而无论要编译的源码在任何目录都可以,且不用设置go.mod。

前台qt后台go起步

→参考指导:

环境:https://github.com/therecipe/qt/wiki

→therecipe/qt包的安装

先go get -u -v 不行就先下载,然后改名适配到代码中包引用的相应GOPATH中,然后再安装命令工具即cmd中的…。

重要是认清go get的本质就是一种git clone的包装。

go install  /home/tarena/code4DN/learn_gopath/src/github.com/therecipe/qt/cmd/...

不出意外是报错的,但看下面的解决问题内容。

→解决go端的环境的问题

https://blog.csdn.net/wzw_mzm/article/details/77618922

出现“找不到 golang.org/x/mod/module”问题,后来手工下载了golang.org/x/下面系列仓库,就是 git clone.

git clone https://github.com/golang/mod.git 
git clone https://github.com/golang/xerrors.git 
这是两个新加入的,一般没有它,已经可以运行demo.最终的完整支持包如下图

原始网上下载运行demo的命令如下,

go get -ldflags="-w" github.com/therecipe/examples/basic/widgets && $(go env GOPATH)/bin/widgets

它会直接运行一个弹出窗口,相应后台的操作是拷贝了代码并编译放在GOPATH/bin中,再运行。
本人已经下载过therecipe/qt包了,就是对应GOPATH下的

github.com/therecipe/examples/basic/widgets/main.go

→解决QT端的环境问题

以上集齐了龙珠。这里是锦上添花,因为,要充分使用QT的伎俩,就需要一套工具。
这时再次执行命令

go install  /home/tarena/code4DN/learn_gopath/src/github.com/therecipe/qt/cmd/...

命令成功使用之后

goqtuic的安装

go get -u -v github.com/stephenlyu/goqtuic

事实上没有这些工具也可以运行demo或QT库的代码。只要thericipe/qt包具备了就行。

总结跨平台

不管是windows还是linux下,都要在GOPATH/src下具备github.com和golang.org。前者里面有therecipe后者里面有x。同样的代码,都用Liteide编译,本地化成各自系统的风格。

静态库的go调用:(用GO来唤醒C的各种沉睡资源吧)
https://www.jianshu.com/p/b3fb41d7c33f

附录:

  • qtsetup会把qt的相应源码下载放置在go源码旁边,如果你有了mingw和gcc,它都会编译成静态库(.a的文件)给你。go帮你丰富环境真是全方位的。如果你是单独完全安装的qt环境,此处可以省略。很久以前,静态编译成window平台的QT库让你累疯,但现在mingw和go,让你永远不碰那个步骤了。
  • 翻墙参考:https://www.cnblogs.com/hupeng1234/p/9727170.html
  • qt如果要调试或用其它QT版本,有几个需要的环境变量比如QT_DIR。

双系统搭建及ubuntu和CentOS下安装Qt5

把大象放冰箱里需要三步,同样,玩linux也需要。第一,制作USB启动盘,第二,安装系统,第三,安装Qt5。

第一篇,材料准备

有多种方式来制作USB启动盘。本人实验了两个,用vmware12和ultraISO.

虚机方式:

建立好空白虚机后,就是提示第一坑。
第一个坑,就是开启intel VT-x.从bios中设置。
重启,再来,可以了,不要装vmware-tool先,不然就在抢占CD-rom。
在我本机S1 yoga的bios上设置两处:
一,sercurity中的安全引导去掉
二,startup中的boot中选择both,即允许传统模式。
用烧录方式:
当然就是把ISO用ultraISO来烧录到USB中了。这个方式不用过多介绍。
当做好USB启用盘后,你F12引导从U盘进入系统,你会看到try和安装两个大按键的情况。我们即可进入第二篇章了。
第二篇章,系统安家
你是租房还是要买房?系统放到你的U盘上还是,想系统在你的硬盘上?这个问题赶快想,尤其是安装步骤到了分区时。但不管如何,选择安装到硬盘是入口。
如果是想在USB上玩linux,那当然安全,不会破环原来的系统。但是磁盘空间,硬件支持和使用体验必须是要慢被理解的。分区方法如下:(我的U盘就16G)
要在U盘上/dev/sdb建立新分支,一个主15G,一个交换分区9百M。
安装不必细说,当出现提示重启时,拔出U盘即可。
当你是个老司机,硬盘富余,且酷的话,来吧,装在硬盘上。并且让windows来当房东。这个意义深远了,因为,如果你想linux撤出,只要格式下那个分区即可。方便的代价就是要懂得原理并实现,还有找到利器,比如easybcd。
原理其实就是:
MBR—-grub2—-bootmgr(由grub来接管系统,在它的分支中选择windows还是linux)
现在:
MBR—-bootmgr—-grub(由windows提供的引导菜单,它当房东,grub就只管引导linux即可,不用去学习grub命令行,好主意)
那个利器就是编辑bootmgr的。所以,我用后面的引导模式了。
用windows的磁盘管理,压缩卷,把最后一个分区给缩小,然后就会多出一个空闲分区,这个就是给硬盘linux的“新房”。
然后,重启用U盘引导,这次同样选择安装到硬盘选项。在分区时,需要充分小心了。
先看看前人的指导:http://blog.csdn.net/pop_rain/article/details/70477085
在我的环境中最终分三个,/,/boot,/home分别为10G,200M,50G,注意引导要放在与/boot同映射的分区上。注意没有/swap区。
因为据说17.04后的版本不需要分交换分区了,而变成了交换文件的方式。
并且,如果你把引导装在了/boot对应的分区,grub2不会跑出来作怪,这是让windows来引导的前提。不然,得用工具修复MBR,所以,装完ubuntu,再重启应该是熟悉的wiondows不是grub。如果是后者,你分区错了。
当你再重启发现进入了熟悉的windows了,没有错,因为,房东管理着客户linux。此时,搬家已经完成,linux入住了,但房东没有给配好钥匙。进系统后,找那个利器吧。easybcd中加一个引导条目,分区选择为/boot那个系统分区。
再重启,windows给你选择权了,让你进linux去吧。不过,我碰到了问题。
最大的坑是:ext4 superblock checksum 。没错,这个是硬盘格式的错误。卡了我一下午。
一个国外帖子搞定了。
先用USB安装盘,启动进去,用root修复好挂载/的那个分区/dev/sda7.
然后,重启硬盘引导后发现可以有root的命令行,看来修复硬盘格式有戏。
然后,就是把其它的两个linux分区修复。之后,ubuntu17.04的用户登陆界面出现。
但最后,反朴归真了,发现在busybox的initramfs的命令提示符下,用 (sudo) fsck.ext4 /dev/sda7,8,9,三次命令后,reboot即可。
终于是躺在我硬盘里的,与win7同床的,让微软引导的小弟系统呀。
第一件事,开启root。
技巧把$变成#,sudo -s.或sudo su
此时安装东东已经够了,但如果你想用root来登陆系统。继续下面操作。
然后执行: vi /etc/lightdm/lightdm.conf.
增加 greeter-show-manual-login=true  allow-guest=false  . 修改完的整个配置文件是
[SetDefaults]
greeter-session=unity-greeter
user-session=ubuntu
greeter-show-manual-login=true #手工输入登陆系统的用户名和密码
allow-guest=false   #不允许guest登录
然后我们启动root帐号:
sudo passwd root
根据提示输入root帐号密码。
重启ubuntu,登录窗口会有“登录”选项,这时候我们就可以通过root登录了。
第三篇章 系统装修
与房东win7磨合得不错,但linux下没啥好玩的就有些寒酸了。装个Qt5来。
如果你是CentOS,这可以这么玩了。
{
一,编译器准备:
yum check-update
yum -y install gcc
yum -y install gcc-c++
—–解释
gcc: yum install gcc
g++: yum install gcc-c++
此外还有以下方法:
yum install make
— 或者
yum groupinstall “Development Tools”
— 或者(这个省事,把系列工具全搞定)
yum install gcc gcc-c++ kernel-devel
二,Qt5依赖库准备:
#yum install mesa-libGL-devel mesa-libGLU-devel
#yum install freeglut-devel

}//end CentOS

ubuntu:
{
首先不可或缺的就是编译器与基本的函式库,如果系统没有安装的话,依照下面的方式安装:
  $ sudo apt-get install build-essential
安装OpenGL Library
  $ sudo apt-get install libgl1-mesa-dev
安装OpenGL Utilities
  $ sudo apt-get install libglu1-mesa-dev
  OpenGL Utilities 是一组建构于 OpenGL Library 之上的工具组,提供许多很方便的函式,使 OpenGL 更强大且更容易使用。
安装OpenGL Utility Toolkit
如果不行就把,sudo apt-get install libglut-dev命令改成
$ sudo apt-get install freeglut3-dev
}//end ubuntu
三.直接运行安装包
#sh qt-opensource-linux-x64-5.5.1.run
四.安装好之后,需要添加环境变量
#vim /etc/profile
在最后一行,添加以下内容:
export PATH=”/opt/Qt5.5.1/5.5/gcc_64/bin:$PATH”
export PATH=”/opt/Qt5.5.1/Tools/QtCreator/bin:$PATH”
如果第四步没有搞好,编译好的测试项目不能运行执行文件。本人就碰到了xcb的插件要求报错。原来在5.5以上的高级Qt版本中,引用了platform的概念。所以,要使用LD_LIBRARY_PATH来找那些库。当然,你找那个qtcreator.sh执行,里面有自动配置好系统环境的处理。
until now,enjoy!

nginx+redis应用服务架构搭建

事实上,两个东东功能独立。nginx作为开源的web服务器,可以用做反向代理等。而redis说白了就是一个内存数据库,存储键值对,可以多节点部署在多个物理机做为应用层,可以集群方式自动管理。可以不用重启,灵活增删节点等。
此处放在一起是因为工作中整理需要。当然,你可以分开阅读或借鉴。
前提:
CentOS6.5 x86_64
一,基础软件:有些并不是必须的补丁。
先用yum install -y XXX,如何需配置本地安装源有本站另外文档介绍。
如果没有yum那必须要有安装光盘的Packages文件夹了,里面是配套的软件包。用rpm -ivh XXX.rpm即可。
gcc的依赖如下:

cloog—–ppl
cpp—–mpfr
g++(gcc-c++)

libstdc++-devel
jdk

使用的openjdk的版本

把起作用的路径先设置成HOME路径,然后加入path。
如,java的默认路径是/etc/alternatives/jre_openjdk
#vi ~/.bash_profile
加入内容:
export JAVA_HOME=/etc/alternatives/jre_openjdk
export JRE_HOME=/etc/alternatives/jre
PATH=$JAVA_HOME/bin:$PATH:$HOME/bin
如下两个补丁包可以略,因为,在nginx的安装过程中也必须要源码编译安装。
PCRE
openssl-devel、pcre-devel、zlib-devel
zlib:
./configure
make
make install
ruby

libruby
ruby-libs
—-libreadline()
cd /path/ruby
./configure -prefix=/usr/local/ruby
make
make install
sudo cp ruby /usr/local/bin
事实上,用yum安装的话:yum install ruby,即可了
rubygems:

首先使用yum install rubygems来“投石问路”,就看到它所依赖的包,然后,在Packages目录里把rdoc和另一个包安装好,
最后,去网上下到了rubygems,
rubygems-1.3.7-5.el6.noarch.rpm
解压安装,成功。
没有yum的情况:
cd /path/gem
sudo ruby setup.rb
sudo cp bin/gem /usr/local/bin
gem-redis:

这是ruby和redis之间的桥,此时yum已经插手不上了。
方法一:
gem install redis –version 3.0.7
#由于源的原因,可能下载失败,就手动下载下来安装
#download地址:http://rubygems.org/gems/redis/versions/3.0.7
wget加url
方法二:
下载gem文件,在上面的url里一定会找到。
现场使用语句
gem install -l /root/tool/redis-3.0.7.gem
二,redis安装和运维:
安装集群:
tar -zxvf redis-3.0.7.tar.gz
mv redis-3.0.7 /usr/local/redis3.0.7
cd /usr/local/redis3.0.7
make
make install
cp /usr/local/redis-3.0.7/src/redis-trib.rb /usr/local/bin/
mkdir -p /usr.local/cluster
cp /usr/local/redis-3.0.7/redis.conf /usr.local/cluster
cd /usr.local/cluster
mkdir 7000
mkdir 7001
mkdir 7002
1)启动节点,或说实例,在/usr.local/cluster/
现行配置redis.conf如下:
daemonize yes
port 9001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
cd 7000;redis-server /opt/redis/conf/redis.conf > redis-0.log 2>&1 &
cd ../7001;redis-server /opt/redis/conf/redis.conf > redis-1.log 2>&1 &
cd ../7002;redis-server /opt/redis/conf/redis.conf > redis-2.log 2>&1 &
2)构建集群关系
#redis-trib.rb的create子命令构建
#–replicas 则指定了为Redis Cluster中的每个Master节点配备几个Slave节点
#节点角色由顺序决定,先master之后是slave(为方便辨认,slave的端口比master大1000)
—单机情况下:
redis-trib.rb create –replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002
—双机情况下:
redis-trib.rb create –replicas 1 130.1.2.11:7000 130.1.2.11:7001 130.1.2.11:7002 130.1.2.12:7000 130.1.2.12:7001 130.1.2.12:7002
3)检测集群工作情况
  #redis-trib.rb的check子命令构建
#ip:port可以是集群的任意节点
redis-trib.rb check 1 130.1.2.11:7000
结果是:
[OK] All nodes agree about slots configuration.
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
说明运行正常了。或者redis-cli -c -p,-h 10.0.0.1 -p 后ping/PONG
现场抓图:
技巧:
重改配置时常用语句:
cd ../7002/;rm nodes.conf -f;mv redis.conf redis.conf.v0
三,nginx安装
版本:
在/root/tool/下进行解压和编译安装。
现场最终起作用的语句:
./configure –with-pcre=pcre-8.12 –with-openssl=openssl-1.0.1c –with-zlib=zlib-1.2.8 –with-poll_module –prefix=/home/linux/nginx/nginx-1.9.4/run –with-stream
make;make install
把安装路径加入到path中,export NGINX_HOME,参考上面java安装。即/home/linux/nginx/nginx-1.9.4/run。
配置文档如下:在/home/linux/nginx/nginx-1.9.4/run/conf下面,名为nginx.conf.
删除http节,如果发现已经存在stream节,即把同名的节替换即可。
stream {
    server {
        listen 80;
        proxy_pass app;
    }
    upstream app {
        server 130.1.2.11:4442;
        server 130.1.2.12:4442;
    }
    server {
        listen 81;
        proxy_pass appp;
    }
    upstream appp {
        server 130.1.2.11:6666;
        server 130.1.2.12:6666;
    }
    server {
        listen 82;
        proxy_pass apppp;
    }
    upstream apppp {
        server 130.1.2.11:4433;
        server 130.1.2.12:4433;
    }
}
.nginx的启动
nginx -c /home/linux/nginx/nginx-1.9.4/run/conf/nginx.conf
重启命令 nginx -s reload
关闭
  1.从容停止:kill -QUIT nginx主进程号 (注释:进程号查询方法;ps -ef|grep nginx 看master进程号)
  2.快速停止:kill -TERM nginx主进程号
  3.强制停止:pkill -9 nginx
测试端口是否开放,当然先装好nc工具
nc -z -w 1 127.0.0.1 8883
可以快速开放一个tcp端口,相当于建立一个socket server:
nc -l 8884
用这个命令开放某个端口穿越防火wall
iptables -I INPUT -p tcp –dport 82 -j ACCEPT
iptables -L -n | grep 82
service iptables save
四,业务程序:

yum本地安装源配置

使用yum要具备工具,所以,安装好这个包很重要。
在Linux下有了它,就像是光夫有机器猫,大圣有了金箍棒。
在/etc/yum.repo.d/目录下,一般会有四个文件。
…………CentOS_Base.repo——-网络源,要想在无网络状态下就要禁用它,重命名,加上.bak
…………CentOS_Media.repo—–这个就是光盘或挂载的文件了,修改它。
在baseurl 中修改第2个路径为/mnt/cdrom(即为光盘挂载点),注意,挂载点下面要有repodata/repomd.xml(这个是纽带)
将enabled=0改为1
然后保存,#yum update后就可以使用了。
注意,还包含一些很长文件名的文件。所以,即使没有光盘,可以把xml和长文件名文件拷出来放到系统内文件夹中。

windows核心编程(第5版)读书笔记一

第一章节 错误处理
几乎所有的windows API返回值都是下列之一:
VOID——不会失败,失败了骚扰bill gates去,
BOOL——不用说了吧,
HANDLE—失败则是NULL,当然有时是-1,
PVOID—–失败是NULL,成功就是指针喽,
LONG/DWORD—-要看具体的上下文环境了。
当调用失败,返回值会先指出已经发生错误。所以要先判断返回值。然后,使用GetLastError()来得到详细的错误提示。返回值是dword类型的,要得到描述,加入WinError.h.
技巧一:在监视中,$err,hr,就会看到调用的API错误的内容。
技巧二:使用VS的IDE小工具,error lookup
只你自己开发的模块想返回不一样的error时,可以使用SetLastError(DWORD)来写入,当然,错误代码要像点样,即32位中的29位要必须为1.而0是给系统用的。
第二章节 字符和字符串的处理
VC6——ANSI,DBCS——-/Zc:wchar_t(这个选项就会有定义wchar_t这个数据类型)
VS201X———–ANSI,UNICODE(指的是UTF-16)
事实上,typedef unsigned short wchar_t;
WinNT.h中统一了类型的名称。
TEXT(param)在unicode宏定义下,在param前加了L前缀。
所以,TCHAR也是个宏,可以配合TEXT(),_T() 来一起变脸。
unicode阵营的后缀或关键字母:
w—wide
L—-
ansi阵营的后缀或关键字母:
a—ansi
中性函数:或会变脸的,应用在两种编码下都可以编译场景,加入TChar.h配合String.h
_tcslen()会变脸成wcslen或strlen
C库的新版本的安全系列函数
1)字符串函数:加入StrSafe.h
_tcs拼加后面的选项即可cpy/cat/再拼接_s后才是安全字符串函数。第二参数为要处理的字符长度,用_countof宏(stdlib.h) 来得出字符数最好,注意不是字节数哟.
StringCch为前缀的也是安全函数。
注意:
使用微软包装的安全函数代替C库函数,好处是即时发现内存操作的异常,但有时也可能会出现“Debug Assertion Failed”对话框。当然要是debug模式下,当然也有办法屏了它,用release或定义InvailidParameterHandler函数,然后注册它,再程序运行开头加入个宏:_CrtSetReportMode(_CRT_ASSERT,0);
判断返回值必须等于宏S_OK,当不是这个值时必须要检查字符串的操作。
2)安全缓冲区函数:加入CrtDefs.h
memcpy_s——–wmemcpy_s
memmove_s——-wmemmove_s
第三章节 内核对象
有SECURITY_ATTRIBUTES结构为参数的生成才是内核对象,区别于GDI和其它的对象。
所以这也揭露了内核对象的本质是—-结构。而句柄则是—–由系统管理着的内存地址
CloseHandle()函数详析:
工作步骤:
1,验证自己主调进程中的句柄表,是否有权访问此句柄。如果有效,则获得内核对象的数据结构地址。
2,把内核对象结构使用计数减1,如果是0了,则销毁。
注意:
如果参数是无效的句柄,CloseHandle返回false,GetLastError返回ERROR_INVALD_HANDLE。如果在调试,则出现0xC0000008的异常抛出。
当函数返回前,清除当前进程的句柄表,所以以后代码不能再使用此句柄了。
当用变量保存过句柄的话,应该设置为NULL。
任务管理器是可以查看程序中的进程句柄表。
跨进程边界共享内核对象—略

windows核心编程(第5版)读书笔记二

第四章节 进程
进程内核对象在创建的时候总会处于未激发,无信号状态,但当进程终止时,系统自动会让进程对象变成激发状态,并且会永远保持这种状态。即回不到未激发状态。
C库会根据三个维度选择入口点函数:
编码,运行模式,运行环境
_tWinMain(WinMain)
wmainCRTStartup
_tmain(wMain)
_tmain(Main)
mainCRTStartup
wWinMainCRTStartup
WinMainCRTStartup
_tWinMain(wWinMain)
编码
ANSI
UNICODE
UNICODE
ANSI
ANSI
UNICODE
ANSI
UNICODE
运行模式
GUI
CUI
CUI
CUI
CUI
GUI
GUI
GUI
运行环境
WIN16
WIN32
WIN16
WIN16
WIN32
WIN32
WIN32
WIN16
在VC自有的C运行库的源代码中,crtexe.c中可以找到以上win16四个函数的源代码。
这些启动函数或者说入口函数的作用是:
1)获取指向新进程的完整命令行的一个指针
2)获取指向新进程的环境变量的一个指针
3)初始化C运行库的全局变量。如果包括了StdLib.h,就可以访问这些全局变量了。
4)初始化内存分配和IO底层
5)调用所有全局和静态C++类对象的构造函数。
系统接管,加载exe,dll到进程的一个地址空间(与链接器有关了),把这个地址返回给第一个入口函数的参数,即实例句柄。
下面可以玩这个句柄了,GetModuleFileName().
如果,你忘记实例句柄了,或没没放到全局里,不过没关系,可以用GetModuleHandle(param).参数可以是一个路径,最好是程序里用到的某个dll,要么,param就是NULL,这样就会得到运行着的当前进程的实例句柄。
命令行和环境变量,最好不要用C运行库初始化后的内容,万一时机没对,还没初始化你就读了,会出问题,所以window有厚道的API。GetCommandLine(),C运行库都在用,你凭啥找事儿,对吧。
技巧一:配合CommandLineToArgvW(GetCommandLine(),&nNum),可以得到友好的命令行参数。
这个配置和系统—》高级系统设置—》系统变量的内容是一致的。
入口点函数完后,就是进程的后事了,包括:
1)C运行库接管,调用自己的exit
2)调用_onexit()此前注册的任何一函数,假如你注册了的话。
3)调用所有全局和静态C++类对象的析构函数
4)如果有DEBUG则可以生成内存泄漏报告,可以深入去研究下。
5)C运行库来调用操作系统的ExitProcess函数,把入口点返回值以参数传入,即退出代码。这样系统就会杀死进程了,此函数返回值是void,它通知OS了,就应该无声息的over了。
注意,有时入口点返回,而有时线程可以调用ExitProcess和TerminalPorcess。
入口函数中显示使用ExitThread的函数,会让主线程退出,但如果其它线程还在工作呢?进程就不会退出,造成僵尸进程的凶手。
入口函数中显示使用ExitProcess的函数,会让C运行库函数没有执行清理资源的机会。
所以,最保险就是永远不显示的调用ExitX之类的函数。
更NB和危险的函数还有,那就是TerminalProcess,它厉害在它可以在某线程里被用,去干掉自己和别人的进程。

进程当前目录
这里要注意,因为,进程下的线程是有能力改写进程的当前目录,这也包括子进程。所以,要注意。
线程会通过GetCurrentDirectory()和SetCurrentDirectory()来存取路径。
做为进程,可以使用GetFullPathName()来看看现在的路径或者根据驱动器去环境变量里找到某路径。

windows核心编程(第5版)读书笔记三

第六章节 线程基础
创建线程,要使用_beginthreadex来代替WAPI提供的CreateThread。因为,要从编译器角度来创建。从用户角度至少看起来没有依赖OS。但事实上,里面还是用了CreateThread.
同样,杀线程,使用_endthreadex.
注:用以上两个库函数的原因是,因为,如果你用了signal函数,那么就要用_end函数来清理资源,可是那样,你就画不圆上下文了。同时使用时要注意有EX来标识的,因为存在着旧的弃用的函数。
CloseHandle是可以传已经被清理的或伪句柄的,只是它会返回false,并且对error置成ERROR_INVALID_HANDLE。
TerminalThread是异步的,只是发信号。要确定被杀的线程死了,要用WaitForSingleObject,向其传递线程句柄来守候。原理就是,线程的内核对象,当引用计数减为0时,会变成激发状态,有信号状态。
GetExitCodeThread是检查线程退出代码的。如果线程还没有退出,返回是STILL_ACTIVE宏的值。如果已经退出,返回true,并有相应值。
微软提供的C/C++库用于本机的开发。
libCMt.lib
库的静态链接发行版本
libCMtD.lib
库的静态链接调试版本
MSVCRt.lib
导入库,用于动态链接MSVCR80.dll(默认库)
MSVCRtD.lib
导入库,用于动态链接MSVCR80D.dll
MSVCMRt.lib
导入库,.net的托管/本机代码混合
MSVCURt.lib
导入库,.net的MSIL代码
线程句柄自获函数:
几乎所有的WAPI函数都要在第一参数传句柄的,所以,当你突然眼前一亮,想用WAPI了,这第一个参数必须难不住你呀。
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
注意:以上两函数返回的是“伪句柄”
原因:
1)它们不会在进程句柄表中新建句柄,当然也不会影响引用计数。当然,CloseHandle()多释放一次,程序不死,只是它返回false。
2)它们返回的句柄要根据运行所在的进程和线程来关联。比如,在父线程中调用了,返回的句柄即使以参数传给子进程,则其指向仍然是子线程的。所以这一点有些像虚函数中的虚指针,只能意会不能言传了。
当然,有时用线程ID做些逻辑时,可以使用:
DWORD GetCurrentProcessId();
DWORD GetCurrentThreadId();
当然,如果你有了ID,你还可以换成句柄。
OpenThread(),下面示例一下转换办法并且,给出一个对进程优先级操作的技巧。
VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend)
{
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwProcessID);
     if(hSnapshot != INVALID_HANDLE_VALUE)
     {
          //walk the list of threads
          THREADENTRY32 te =  {sizeof(te)};
          BOOL fOK = Thread32First(hSnapshot, &te);
          for(; fOK; fOK = Thread32Next(hSnapshot, &te))
          {
              if(te.th32OwnerProcessID == dwProcessID)
               {
                    //主角登场
                    HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
                    //略过对hThread的判断
                    if(fSuspend)
                         SuspendThread(hThread);
                    else
                         ResumeThread(hThread);
                    CloseHandle(hThread);
               }
          }//endfor
          CloseHandle(hSnapshot);
     }
}
最后,再赠送两个函数用于获取进程,线程运行的时间。
GetProcessTimes(),GetThreadTimes()
第七章节 线程调度,优先级和关联性
线程可以自己挂起,但不能自己恢复,并且,挂几次要应该恢复几次(ResumeThread)。挂起可以在线程生成时以参数传入,也可以用SuspendThread来人工自由操作。
第八章节 用户模式下的线程同步
技巧:
原子操作的系列WAPI函数:InterLocked*
+ExchangeAdd
+Increment
+ExchangePointer
volatile关键字,用来声明,后面的变量不能被优化,要去不断从内存来读取。
进阶一段:CRITICAL_SECTION结构和EnterCriticalSection和LeaveCriticalSection
要声明个全局的CS变量,然后用前初始,用后删除。
TryEnterCriticalSection比较灵活,做人当如此,能锁定就锁定段,没有段可用时,就立刻通知调用者。
同时,也不要把初始化关键段看低,因为,能避免交给内核态就晚点交,不然,上下文切换的步骤很耗时,耗资源的。所以,给初始化传值或用Set来设置抢段的重试时间,InitializeCriticalSectionAndSpinCount(p1,p2),p1是句柄了,p2大约4000。
注意:
线程抢锁的顺序要一致,否则死锁,即在锁包锁的情况下。
关键段的使用只能在一个进程内来控制其中众线程的同步,并且不能根据时间来等待。
进阶二段:条件变量
线程想把锁释放并把自己阻塞,就使用条件变量。
注意,这时,你得玩两个内核对象才行,即条件变量,必须配合锁。
首先看看这个阻塞函数,我特喜欢微软用sleep来前缀,因为,可读性很高。体现了两层意思:1,这是阻塞的,2,这是有时间参数的,时间到了没拿到条件变量就是false.
SleepConditionVariableSRW或SleepConditionVariableCS看吧,后缀又说明了要配合的锁。够意思。
我不够意思了,不列参数,自己去查手册喽。
有了Sleep就得有Wake吧。它会使等待同一个条件变量被触发的线程得到锁并返回。然后就干活呗,但得到锁了就得释放它。但它不会同时唤醒其它正在等待同一个条件变量的线程。
要看自己的实际需要。反正也是有WakeAll*和共享锁和独占锁来设计。
第九章节 内核态用内核对象进行线程同步
进程和线程内核对象在操作系统的处理上一样设计的。见笔记二的进程描述。
本章节介绍了另外的内核对象来帮助我们玩转线程同步。
1,事件
2,可等待的计时器
3,信号量
4,互斥量
头大吧,不过,我们要想掌握它,必须用不同的维度和结构去3D它。
首先,了解基础,或者说这个是第一个维度。
前进了解了进程和线程,有信号和无信号的规则,那么,这四个对象呢,look
事件:
引用计数器
自动重置/手动重置———–初始参数方式,CreateEvent
是否被触发——————-函数控制,SetEvent,ResetEvent
手动重置事件:
被触发时:等待此事件的所有线程都是会变成可调度状态。
自动重置事件:
被触发时:等待此事件的一个线程,只有一个线程会变成可调度状态。
因为自动重置会在一个线程得到事件对象后,自动把自己变成未触发状态。系统代劳的。
可等待的计时器:
指定时间或每隔一定时间触发
引用计数器
自动重置/手工重置——-初始化方式,CreateWaitableTimer,和事件一样没有其它的设置方式
SetWaitTimer是生成了内核对象后,需要进一步应用时的必经之路。因为,创建后,计时器都是属于未触发状态。
信号量:
引用计数器
最大资源量————-池里的资源总数
当前资源数————-目前应用了资源的数量,用RealseSemaphore来递增
互斥量:
引用计数器
线程ID———–内部自己管理,当计数为1时,则用调用的当前线程ID来填充。
递归计数———是否要触发

windows核心编程(第5版)读书笔记四

第19–20章节 dll的基础和高级技术
入口点函数:DllMain()
一般用来执行一些进程,线程有关的初始化和清理工作。要么不实现它,要么实现正常,返回true,否则,dll可能就不能被使用。
注意:
区分大小写的,否则就是无用的。
隐式调用dll时,系统启动时就会用到DllMain(),而显式调用时,在LoadLibraryex中来调用。并且,切入点是DLL_PROCESS_ATTACH
当引用了dll的exe要建立个新线程时,会检查所以已经被调入进程空间的dll的DllMain。并传入DLL_THREAD_ATTACH。有一个例外就是主线程切入仍以process来通知dll.

自动关闭程序屏蔽windows对话框

windows server 2012关闭无响应程序对话框?
windows server 2012不提示是否要联机查找解决方案对话框?
只要干脆利落的自动关闭程序。那么follow me.有几点可以试试。
  • 关闭无响应程序
在Vista和Windows 7及以上的OS上,参照以下方法:
■在开始运行中输入regedit并回车
■定位到HKEY_CURRENT_USER\Control Panel\Desktop
■设置AutoEndTasks键值为1,如果没有可以手动创建一个名为 AutoEndTasks 类型为REG_SZ值为1的表项。
■WaitToKillAppTimeout是超时等待时间,默认值12000,这个值在很多网站上建议修改短一点,这里不推荐,最好不要改。因为程序的运行是综合的,影响超时的时间会很多,太短的超时时间可能会带来一些“莫名其妙”的问题。
如确认修改WaitToKillAppTimeout,请统一修改:
HKEY_CURRENT_USER\Control Panel\Desktop
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
下的WaitToKillAppTimeout,比如1000,2000均可以。
  • 关闭问题报告:
控制面板–系统和安全—操作中心—问题报告设置
点选“从不检查解决方案(不推荐)”
UAC设置方法/步骤:
你可以完全关闭UAC,在控制面板–系统和安全—操作中心中。也可以通过下面的步骤来设置它。(但要想干脆利落,你知道咋办)
1,点击控制面板,选择所有控制面板项,点击用户帐户
2,点击“更改用户账户控制设置”弹出计算机用户安全通知设置,始终通知(高):这是最安全的设置,收到通知后,你应该先仔细阅读每个对话框中的内容,然后才允许对电脑进行更改。
3,始终通知(中):如果系统允许对 Windows 设置进行更改而不通知你,则表明这种更改是安全的。但是,Windows附带的某些应用可以将命令或数据传递给它们,恶意软件可能会利用这一点,使用这些应用在电脑上安装文件或更改设置。应该始终小心允许在电脑上运行的应用。
4,始终通知(中低):与“仅当应用尝试更改计算机时通知我”相同,但是不会降低桌面亮度。如果选择此选项,则其他应用可能会影响用户帐户控制对话框的可视外观。这是一个安全风险,尤其是你的电脑上存在恶意软件时。
5,从不通知:这是最不安全的设置。将用户帐户控制设置为从不通知时,你便有效地关闭了用户帐户控制。这会使得你的电脑面临潜在的安全风险,这个设置一般在虚拟机练习时候设置
  • 关闭“已停止工作”对话框
 最近发现一个很早以前的程序出现了兼容性问题。程序有检测机制,发现异常退出可以自动重启。但是这次没有重启成功。操作系统是Windows 2008,以前用的操作系统是Windows 2003,在2003上就没有该问题。
后来发现2008和2003的错误报告机制不同。2008下,遇到程序崩溃会弹出一个错误提示对话框,需要手工关闭,程序才能退出。

临时解决问题的方法就是想办法关闭这个对话框。Windows有很多错误提示框,关了一个还会出现另外一个。
下面的方法可以关闭以下的几个对话框不再出现:
xxx已停止工作
xxx-应用程序错误
xxx-未找到调试器

需要修改三个地方:
1.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
在.NETFramework上点击右键-》新建-》DWORD(32-位)值-》
名称:DbgJITDebugLaunchSetting
数据:1
2.HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting 修改两个值(修改第一个值也可退出,但是退出时间较长,测试环境需要1分钟左右,应该是在收集错误信息)
名称:DontShowUI    数据:1

名称:Disabled      数据:1
  • 关闭错误报告
下面这句在开始—-运行中键入,效果是关闭server的错误报告,适用于2008 server。可以用/query,/详细,/摘要,/summary来替换如下的禁用。
serverWerOptin /禁用
我发现了另外引导的 MSDN如何从用户可以抑制嵌入式系统上发生的系统和应用程序的错误信息。注册表中的位置是在以下默认情况下,该数值数据为0,我们应该将其更改为2设置为不可见的所有邮件。
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Windows\ErrorMode.
  • XP关闭无响应方案:
首先打开注册表:在[开始]–>[运行]–>键入[Regedit];  然后找到相关项目按照以下步骤进行设置:  左侧列表中依次展开,找到[HKEY_CURRENT_USER\ControlPanel\Desktop],这个就是设置软件无响应时的选项。将里面AutoEndTasks的数值从0修改为1就是让系统自动关闭无响应的软件。