很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能够启动运行,方法是写注册表Software\\Microsoft\\Windows\\CurrentVersion\\Run。
参考程序可以见下:(查找程序目录的执行文件,存在则进行添加注册表操作)
//实用代码一
int C***Dlg::CreateRun(void) {
//添加以下代码 HKEY RegKey; CString sPath;
GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer();
int nPos;
nPos=sPath.ReverseFind('\\');
sPath=sPath.Left(nPos);
CString lpszFile=sPath+"这里加上你要查找的执行文件名称 CFileFind fFind;
BOOL bSuccess;
bSuccess=fFind.FindFile(lpszFile);
fFind.Close();
if(bSuccess)
{
CString fullName;
fullName=lpszFile;
RegKey=NULL;
RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&RegKey);
RegSetValueEx(RegKey,"getip",0,REG_SZ,(const unsigned char*)(LPCTSTR)fullName,fullName.GetLength());//这里加上你需要在注册表中注册的内容
this->UpdateData(FALSE);
}
else
{
//theApp.SetMainSkin();
::AfxMessageBox("没找到执行程序,自动运行失败");
exit(0);
}
return 0;
}
//把上面的getip(共2处)替换成自己想启动程序的名字。
实用代码二:
//写入注册表,开机自启动 HKEY hKey;
//找到系统的启动项 LPCTSTR lpRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
//打开启动项Key long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey);
if(lRet == ERROR_SUCCESS)
{
char pFileName[MAX_PATH] = {0}; //得到程序自身的全路径
DWORD dwRet = GetModuleFileName(NULL, pFileName, MAX_PATH); //添加一个子Key,并设置值 // 下面的"getip"是应用程序名字(不加后缀.exe)
lRet = RegSetValueEx(hKey, "getip", 0, REG_SZ, (BYTE *)pFileName, dwRet);//关闭注册表
RegCloseKey(hKey);
if(lRet != ERROR_SUCCESS)
{
AfxMessageBox("系统参数错误,不能随系统启动");
}
}
一、当前用户专有的启动文件夹
这是许多应用软件自动启动的常用位置,Windows自动启动放入该文件夹的所有快捷方式。用户启动文件夹一般在:\Documents and Settings\<用户名字>\「开始」菜单\程序\启动,其中“<用户名字>”是当前登录的用户帐户名称。
二、对所有用户有效的启动文件夹
这是寻找自动启动程序的第二个重要位置,不管用户用什么身份登录系统,放入该文件夹的快捷方式总是自动启动——这是它与用户专有的启动文件夹的区别所在。该文件夹一般在:\Documents and Settings\All Users\「开始」菜单\程序\启动。
三、Load注册键
介绍该注册键的资料不多,实际上它也能够自动启动程序。位置:HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows\load。
四、Userinit注册键
位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon\Userinit。这里也能够使系统启动时自动初始化程序。通常该注册键下面有一个userinit.exe,如图,但这个键允许指定用逗号分隔的多个程序,例如“userinit.exe,OSA.exe”(不含引号)。
五、Explorer\Run注册键
和load、Userinit不同,Explorer\Run键在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下都有,具体位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run。
六、RunServicesOnce注册键
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce。
七、RunServices注册键
RunServices注册键指定的程序紧接RunServicesOnce指定的程序之后运行,但两者都在用户登录之前。RunServices的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices。
八、RunOnce\Setup注册键
RunOnce\Setup指定了用户登录之后运行的程序,它的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\Setup。
九、RunOnce注册键
安装程序通常用RunOnce键自动运行程序,它的位置在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce和HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce。HKEY_LOCAL_MACHINE下面的RunOnce键会在用户登录之后立即运行程序,运行时机在其他Run键指定的程序之前。HKEY_CURRENT_USER下面的RunOnce键在操作系统处理其他Run键以及“启动”文件夹的内容之后运行。如果是XP,你还需要检查一下HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx。
十、Run注册键
Run是自动运行程序最常用的注册键,位置在:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run。HKEY_CURRENT_USER下面的Run键紧接HKEY_LOCAL_MACHINE下面的Run键运行,但两者都在处理“启动”文件夹之前。
有时候人们往往会为了一个程序的启动而头痛,因为一些用户往往不知道那些文件是如何启动的。所以经常会有些没用的东西挂在系统上占用资源。有时候也会有人因为不知道如何启动某个文件而头痛。更有些特洛依木马的作者因为不清楚系统的自启动方式而使自己的木马轻松被别人发现……
Windows的自启动方式其实有许多方式。除了一些常见的启动方式之外,还有一些非常隐蔽的可用来启动文件的方式。本文总结如下,虽然不是全部,但我想应该会对大家有所帮助。文章全部以系统默认的状态为准,以供研究。
其中(English)代表英文操作系统,(Chinese)代表中文操作系统。本文没加说明指的全为中文Windows98操作系统。
警告: 文中提及的一些操作可能会涉及到系统的稳定性。例如如果不正确地使用注册表编辑器可以导致可能重新安装系统这样严重的问题。微软也不能保证因不正常使用注册表编辑器而造成的结果可以被解决。笔者不对使用后果负责,请根据自己的情况使用。
Windows的自启动方式:
一.自启动目录:
1.第一自启动目录:
默认路径位于:
C:windowsstart menuprogramsstartup(English)
C:windowsstart menuprograms启动(Chinese)
这是最基本、最常用的Windows启动方式,主要用于启动一些应用软件的自启动项目,如Office的快捷菜单。一般用户希望启动时所要启动的文件也可以通过这里启动,只需把所需文件或其快捷方式放入文件夹中即可。
对应的注册表位置:
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders]
Startup=\"%Directory%\"
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerUser Shell Folders]
Startup=\"%Directory%\"
其中“%Directory%”为启动文件夹位置。
英文默认为: C:windowsstart menuprogramsstartup
中文默认为: C:windowsstart menuprograms启动
在开始菜单的“启动”文件夹是可更改的,如果用户更改了启动文件夹,则以上注册表的键值均会改变为相应的名称。
值得注意的是:开始菜单的“启动”文件夹中的内容虽然在默认的状态下可以被用户看得一清二楚。但通过改动还是可以达到相当隐蔽地启动的目的的:
本文链接
第1章 C语言背后的故事 程序设计和C语言 1
1.1 计算机程序是什么 什么是计算机程序 1
作者连什么是程序都讲错了。Word.exe、QQ.exe这些都是(可执行)文件,而不是程序。(P1)
该小节中有三处出现“指令”,然而其含义并不一致。对于技术书籍来说,概念内涵不一致是一种致命的硬伤。表明作者缺乏起码的技术素养。
“程序就像一个‘传令官’”这个比喻是不伦不类的,因为程序本身就是命令,就是指令的集合。(P1)
1.2 计算机语言又是什么 什么是计算机语言 1
鹦鹉学舌般地把谭浩强说错的话又重复了一遍:
“谭老师对这个问题给出的答案是:“人和计算机交流,也需要解决语言问题。需要创造一种计算机和人都能识别的语言,这就是计算机语言。”这段话给计算机语言下了一个定义”。(P1)
事实上根本就不存在“计算机和人都能识别的语言”
1.2.A 如何用计算机语言来表达一个程序 2
第3页的代码是对初学者的误导。(P3)
#include "stdio.h"这种写法虽然不能算错,但绝对反映了作者自己的业余水准。(P3)
int main(),在“()”内不写void,在正规的写法中属于绝不提倡的写法。(P3)
printf("Hello World");这个也不能说是错误,但是这句函数调用中不写\n,是编程是素养问题。(P3)
“第二步:将源代码编译成可执行文件,讲的都是“可执行文件”,而“第三步:计算机执行可执行程序 ”却很突兀地开始讲“可执行程序”,足见作者概念混乱不堪。(P3~4)
“第三步:计算机执行可执行程序,最荒唐的一句话是“……这些指令会被调入计算机,虽然我们人类看不懂这些指令,但是计算机却能够看懂,最终将其翻译成“0101”的机器语言”,(P4)都开始执行程序了却还要"最终""翻译",这是任何学过《计算机基础》的人都不会犯的错误。
第4页“一个C语言程序的一生”这个图更搞笑,因为居然没有内存和CPU,只要有磁盘光盘和输出设备就可以了。而所谓“一个C语言程序的一生”更是不知所云的胡扯。什么叫“C语言程序”?压根就没有定义。图中出现的分别是源程序及可执行文件,他们根本不是同一种东西,怎么可以并称为“C语言程序”呢?另外,所谓“一生”是指从生到死,程序难道是一次性使用的吗?恐怕幼儿园孩子都知道程序是重复使用的。(P4)
这个图还有另一个错误,就是左边源程序要求输出Hello World,而右边显示器输出的是Hello Word。(P4)
1.2.B 从汇编语言到高级语言——风格各异的计算机语言 4
开篇讲到
“包括谭老师介绍的机器语言、符号语言以及高级语言,但是实际上,机器语言和符号语言我们都很少用到,更多的,我们与计算机沟通是通过高级语言,也就是我们在这里要介绍的高级程序设计语言。”(P4)
从这里看,作者是打算后面介绍高级语言。可是,紧接着,作者又开始讲起了“汇编语言”。行文混乱,作者和编辑都有责任。
在“汇编语言”中毫无依据地断言“即使全部用汇编语言来编写Windows的应用程序也不是一件难事”,后来发现这句话是从网上错漏百出的垃圾资料中复制粘贴来的。
不只于此,第4、5、6页的主要内容都是从网上低劣的垃圾资料抄袭而成。甚至连“C++语言是一种优秀的面向对象程序设计语言,它在C语言的基础上发展而来,但它比C语言更容易
为人们学习和掌握。”这样完全违背常识的错误观点,作者也一样原封不动地抄到了书中。(http://baike.baidu.com/view/49.htm http://blog.csdn.net/qj6549/article/details/2901808)
1.3 C语言真正的特点及其演变 C语言的发展及其特点 6
依然是不问对错,抄袭网上低劣的垃圾资料。(http://blog.csdn.net/qj6549/article/details/2901704)
个别地方,例如“C语言……因为其灵活性,尤其加之须对软硬件特点有更多了解(难在语言层面之外)”(P7)是作者的错误观点。其他的错误观点还有:
“C语言在某些需要对硬件进行操作的应用场景下,例如嵌入式系统中,成为程序员们的不二之选。” (注:不顾事实)
“诸如Linux内核、搜索引擎算法,以及大型的科学计算程序等等,恐怕只有C语言才能够胜任。这也决定了C语言在这些领域具有长久的生命力,始终处于一种无可替代的地位”(注:不顾事实的信口开河)
“但是,在开发一些更加复杂的业务型系统的时候,因为其抽象层次比较低,这样的设计方法却可能让整个项目陷入“需求变化”的深渊,一旦需求发生变化,则可能需要对整个系统的设计进行变更,这使得C语言无法很好地支持复杂的大型系统的开发,极大地限制了C语言的应用。这也是为什么后来出现了面向对象的设计思想以及C++语言。”(注:这也是在胡扯,作者完全不了解面向对象的历史,面向对象在1960年就已经出现了,1970年代已经成熟,而C语言出现于1970年,1970年代后期才得到大规模推广和广泛认同及应用)
1.3A C语言与C++不得不说的那点事 8
"在对硬件资源的操作上,C语言更加直接,而C++语言则相对温和一些",(P8)不知所云的信口开河。
插图中说C语言“屹立江湖50年”,(P8)实际上C语言刚刚诞生四十多年。
甚至对作者比较熟悉的C++语言,也有很多不切实际的偏颇论断甚至捏造之词。如
“而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的实际问题,这样就可以通过获取对象的状态信息得到输出或实现对过程或事务的控制。”(P8)
“所以C语言与C++语言的最大区别在于它们的用于解决问题的思想方法不一样”(P8)
“之所以说C++比C更先进,是因为“设计”这个概念已经被融入到C++之中,而单就语言本身而言,在C中更多的是算法的概念。”(P8)
“C++语言比C语言优秀”(P8)
“C语言可以说是C++语言的一个自治子集”(P8)
“很多C++语言不愿意干的脏活累活,C语言干起来快活得很。例如某些对性能要求极高的大型系统,诸如搜索引擎算法、银行
有两种方法:
1.作为成员函数,接受一个参数。
2.作为友元函数,接受两个参数。
class add
{
public:
add():m_n(0){}
add operator+(const add &aR)
{
add a;
a.m_n = m_n * 10 + aR.m_n;
return a;
}
int m_n;
};
// 作为友元函数,接受两个参数。
class complex
{
public:
complex():m_n(0){}
friend complex operator+(const complex &cL,const complex &cR);
int m_n;
};
complex operator+(const complex &cL,const complex &cR)
{
complex c;
c.m_n = cL.m_n + cR.m_n;
return c;
}
int main()
{
add a1,a2,a3;
a1.m_n = 1;
a2.m_n = 2;
a3 = a1 + a2;
complex c1,c2,c3;
c1.m_n = 100;
c2.m_n = 50;
c3=c1+c2;
return 0;
}
url:http://greatverve.cnblogs.com/archive/2013/02/03/cpp-operator-add.html
参考:
C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的。这一系列我将主要讲解C++中有关运算符重载方面的内容。在每一个系列讲解之前,都会有它的一些基础知识需要我们去理解。而运算符重载的基础就是运算符重载函数。所以今天主要讲的是运算符重载函数。
1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不同行为的发生。比如
2 int i1=10,i2=10;
3 i=i1+i2;
4 std::cout<<"i1+i2="<<i<<std::endl;
5
6 double d;
7 double d1=20,d2=20;
8 d=d1+d2;
9 std::cout<<"d1+d2="<<d<<std::endl;
在这个程序里"+"既完成两个整形数的加法运算,又完成了双精度型的加法运算。为什么同一个运算符"+"可以用于完成不同类型的数据的加法运算?这是因为C++针对预定义基本数据类型已经对"+"运算符做了适当的重载。在编译程序编译不同类型数据的加法表达式时,会自动调用相应类型的加法运算符重载函数。但是C++中所提供的预定义的基本数据类型毕竟是有限的,在解决一些实际的问题时,往往需要用户自定义数据类型。比如高中数学里所提到的复数:
2 {
3 public:
4 double real;//实数
5 double imag;//虚数
6 Complex(double real=0,double imag=0)
7 {
8 this->real=real;
9 this->imag=imag;
10 }
11 }
假如我们建立两个复数,并用"+"运算符让它们直接相加:
2 sum=com1+com2;
那么会提示没有与这些操作数匹配的 "+" 运算符的错误。这是因为Complex类类型不是预定义类型,系统没用对该类型的数据进行加法运算符函数的重载。C++就为运算符重载提供了一种方法,即运算符重载函数。其函数名字规定为operator后紧跟重载运算符。比如:operator+(),operator*()等。现在我们给上述程序声明一个加法运算符的重载函数用于完成复数的加法运算:
2 #include <iostream>
3
4 class Complex //复数类
5 {
6 public:
7 double real;//实数
8 double imag;//虚数
9 Complex(double real=0,double imag=0)
10 {
11 this->real=real;
12 this->imag=imag;
13 }
14 };
15
16 Complex operator+(Complex com1,Complex com2)//运算符重载函数
17 {
18 return Complex(com1.real+com2.real,com1.imag+com2.imag);
19 }
20
21 int main()
22 {
23 Complex com1(10,10),com2(20,20),sum;
24 sum=com1+com2;//或sum=operator+(com1,com2)
25
26 std::cout<<"sum的实数部分为"<<sum.real<<