var path = require("path");
var url = path.resolve('./');
转载于:https://www.cnblogs.com/benchan2015/p/5048855.html
《女性学知识讲座》(以下简称《讲座》)中最让我(或者说是我们)感兴趣的莫过于《恋爱、婚姻与家庭》一节,很大的原因在于我们处于一个特殊的时期——大学时期。这是一个开放的、“被允许”的时期,也是一个危险的时期。
我曾经阅读过一些关于恋爱、婚姻的书籍,力求为自己的未来开辟一条“光明大道”,这也是我选《讲座》的原因之一。关于恋爱的课程心得,我就恋爱中最动荡的两个阶段来讨论:初恋期、平淡期。
在我了解到的有限的情况内,大一是大学中最容易让人坠入“爱河”的时期,包括我身边的好几位同学都是如此。其中最让人值得思考的原因就是:寂寞。我们很大部分的同学都是“背井离乡”孤身一人来到大学的,这是他们第一次面对这种环境,难免会心生怀乡之情。然而当他们没有适当处理好这份感情,就会把这份感情错误地转移到其他人身上以寻求庇护,这时就产生了需要“恋爱”的感觉,这就像我们会把处于恐惧时产生的感觉误以为是对此时出现的某位异性的一见钟情一样。
问:我恋爱了,可是我知道这份感情没有未来……可是失去这个人,我会非常不快乐。我要怎么做才让自己摆脱这样的处境?
克:失去这个人之后所感受到的寂寞、苍凉、痛苦,在你还没恋爱以前就存在了。你所谓的爱只是一种刺激,暂时掩盖你的空虚。你通过一个人来逃避寂寞,利用这个人掩盖寂寞,你的问题不在于这段关系,而是你自己的空虚。[3]
从这里我们可以看出,大一学生所谓的恋爱实际上是对“爱”的一种误解,也是一种逃避方式,这也很容易解释为什么当他们适应了大学生活以后很容易分手。这也是以“追求精神满足”为择偶取向的一种表现。
我们常说的“坠入爱河”,其实大多数的情况下,是小我的欲求(wanting)和需求(needing)的一种强化……它和真爱一点关系也没有,真爱之中是无欲求的。西班牙文是最能诚实表达传统之爱的一种语言:te quiero的意思是“我要你”还有“我爱你”。另外一种我爱你的表达方式te amo却很少人用,因为它的意思就是清楚的“我爱你”,并不模棱两可。或许这是因为真爱本来就难寻。[2]
这和上文是如出一辙的,这种欲求和需求正是寂寞所催生的。因此我们应该教育、帮助大一新生面对实在的“寂寞”,这对大学生未来发展会起到积极的作用,同时也可以避免女性在不正确的恋爱中受到伤害。
平淡期是最让人揪心的,很多情侣都是在这个时期处理不好而未能步入婚姻的殿堂。为什么热恋后的男女几乎都吵过架,恋爱中充满冲突吗?事实上“恋爱的感觉是完全没有冲突的。陶醉在爱里并不会耗损精力。耗损精力的是后一段的故事——嫉妒、占有、猜忌、怀疑、恐惧失去那份爱、不断地要求保证和保障。”[3]我的一位同学告诉我,她确实是因为大一感到寂寞无助,而与一位高中同学发展异地恋的,现在他们在一起已经两年了,期间她的男朋友在她的QQ上删除了她的多位男性好友。不难想象出这是猜忌、怀疑、恐惧失去爱的产物,显然这是不道德的恋爱行为,但是这又是情理之中的。这也是社会缺乏诚信以及“小三”案例层出不穷对社会产生的负面影响的体现。所以《讲座》上讨论过的“小三”问题,我认为这不仅仅是当事人的问题,还是一种社会问题。“以‘最大’的麦穗作为衡量的标准,选摘麦穗的人生便失去了欢乐和趣味;以自己’满意’的麦穗作为选摘的标准,人人都可以有自己的快乐。”[4]因此,“小三问题”“平淡期问题”都可以归结为小我欲望的扩张,那么问题便成了如何正确对待欲望扩张了。
最后谈一谈我对婚姻的理解。我认为婚姻甚至是恋爱都是要以经济力量为基础的。你可以不厌其烦地对你的伴侣说“我爱你”,但总有一天他(她)会对你说“我饿了”。因此,我是坚决反对裸婚的。“爱情和婚姻都是合作的一面——这种合作不仅仅是为了两个人的幸福,而且也是为了人类的权益。”[1]可以说,裸婚不是两个人的事,这涉及到下一代人的教育、健康等问题,这几乎都是经济上的问题。这是商品社会中必然存在的现象,因为我认为用经济力量支撑起的爱情和婚姻会比只有感情、道德支柱的爱情和婚姻来得实在。
参考文献
[1] 阿德勒. 超越自卑[M]. 北京:经济日报出版社,1997.
[2] 艾克哈特•托尔. 张德芬 译. 新世界:灵性的觉醒[M]. 海口:南方出版社,2008.
[3] 克里希那穆提. 爱的觉醒[M]. 深圳:深圳报业集团出版社,2006.
[4] 蔚泓. 爱情经济学随笔:如何让我遇见你[M]. 中国社会科学出版社,2008.
转载于:https://www.cnblogs.com/aujun/p/3813852.html
cl;
img=imread('mask.jpg');
imshow(img);
[x,y]=size(img);
img_man=zeros(x,y);
img_com=zeros(x,y);
%% 直方图均衡化算法
Max=max(max(img));
Min=min(min(img));
Hist=zeros(1,256);
for i=1:x
for j=1:y
Hist(img(i,j)+1)=Hist(img(i,j)+1)+1;
end
end
figure,plot(Hist);
p=zeros(1,256);
for i=1:256
p(i)=Hist(i)/(x*y);
end
figure,plot(p);
c=zeros(1,256);
for i=1:256
c(i)=sum(p(1:i));
end
figure,plot(c);
for i=1:x
for j=1:y
img_man(i,j)=c(img(i,j)+1)*(Max-Min)+Min;
end
end
figure,imshow(uint8(img_man))
Hist2=zeros(1,256);
for i=1:x
for j=1:y
Hist2(img_man(i,j)+1)=Hist2(img_man(i,j)+1)+1;
end
end
figure,plot(Hist2); %% matlab直方图均衡化函数
img_com=histeq(img); figure,imshow(img_com)
Hist3=zeros(1,256);
for i=1:x
for j=1:y
Hist3(img_com(i,j)+1)=Hist3(img_com(i,j)+1)+1;
end
end
figure,plot(Hist3); 转载于:https://www.cnblogs.com/tiandsp/archive/2012/03/04/2379283.html
#include <iostream>
using namespace std;
int main()
{
double a[] ={2,2,2,
3,2,4,
1,3,9};
double b[] = {1,0.5,2.5};
double m =0;
int n=3;
for (int i = 0; i < n-1; i++)
{
for (int j = i + 1; j < n; j++)
{
m = a[j*n+i] / a[i*n+i];
b[j] = b[j] - m * b[i];
for (int k = i; k < n; k++)
{
a[j*n+k] = a[j*n+k] - m*a[i*n+k];
#include <windows.h> // Windows的头文件
#include <gl\gl.h> // OpenGL32库的头文件
#include <gl\glu.h> // GLu32库的头文件
#include <gl\glaux.h> // GLaux库的头文件
#include <gl\glut.h> // Glut库头文件
#pragma comment( lib, "opengl32.lib") // OpenGL32连接库
#pragma comment( lib, "glu32.lib") // GLu32连接库
#pragma comment( lib, "glaux.lib") // GLaux连接库
#pragma comment( lib, "glut.lib") // Glut链接库
int screenWidth=640;
int screenHeight=480;
void myInit()
{
glClearColor(1.0,1.0,1.0,0.0); //设置背景颜色为亮白
glColor3f(0.0f,0.0f,0.0f); //设置绘图颜色为黑色
glPointSize(4.0); //设置点的大小为4*4像素
glMatrixMode(GL_PROJECTION); //设置合适的矩阵
glLoadIdentity(); gluOrtho2D(0.0,screenWidth,0.0,screenHeight);
}
void drawDot(int x,int y)
{
glBegin(GL_POINTS);
glVertex2i(x,y); //画一些点
ModuleNotFoundError: No module named 'cv2' 解决方法: pip install opencv-python
我们在应用层调用一个Win32 API, 系统内部究竟是如何执行的, 它是如何从用户态进入到内核态的呢 ?
对于每层一些概念的解释,这里不详述了,具体可以参考理解Windows内核模式与用户模式.
以Kernel32里的 CreateProcess 为例, 内部会调用ntdll.dll里导出的NtCreateProcess, ntdll.dll通过一个中断请求int 2Eh(Sysenter)进入内核态, 在内核的Executive Service Routines 层, 内部保存着一张表 “SSDT”(System Service Descriptor Table,系统服务描述符表), 通过该表找到该API在执行体 (Executive)(ntoskrnl.exe)中导出函数的位置,最终调用系统功能。
下面是另外一张《Windows图形编程》中提到的系统架构图, 我们也可以参考一下:
最后, 总结一下, 微软在Intel处理器上开发Windows操作系统, 我们在Windows操作系统上开发应用程序,无非是一层层的封装, 其实具体到细节, 每层都没有太多神秘的东西。我们当然不可能掌握每层的细节, 只能理解每层的概念, 以帮助我们在应用层更好的开发。
转载于:https://www.cnblogs.com/weiym/archive/2013/01/13/2858357.html
http://www.cnblogs.com/chenxizhang/archive/2008/09/14/1290735.html
也许你从来没有考虑过类型转换和操作符重载的问题,毕竟在很多时候,我们都是系统标准类型,使用内置的一些转换函数和操作符。
但是假设你经常性地需要创建自定义类型(或者结构体),同时你想为它们都实现更加丰富的效果,那么了解.NET所支持的类型转换和操作符重载就显得有些必要了
下面看看一个结构体的定义
public struct MyStruct { public string Name; /// <summary> /// 这是一个操作符重载,但他的作用是做类型转换,而且是隐式类型转换(implicit) /// 这个操作符的具体意义就是可以把字符串转换为一个对象 /// </summary> /// <param name="s"></param> /// <returns></returns> static public implicit operator MyStruct(string s) { return MyStruct.Parse(s); } /// <summary> /// 手工地编写一个处理器(Parse)函数,表示从其他格式转换为对象 /// </summary> /// <param name="s"></param> /// <returns></returns> static public MyStruct Parse(string s) { MyStruct m = new MyStruct(); m.Name = s; return m; } /// <summary> /// 重写该方法的目的是可以用一个字符串来表示一个对象 /// </summary> /// <returns></returns> public override string ToString() { return string.
Template模板模式定义:
定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中.
使用Java的抽象类时,就经常会使用到Template模式,因此Template模式使用很普遍.而且很容易理解和使用。
public abstract class Benchmark
{
/**
* 下面操作是我们希望在子类中完成
*/
public abstract void benchmark(); /**
* 重复执行benchmark次数
*/
public final long repeat (int count) {
if (count <= 0)
return 0;
else {
long startTime = System.currentTimeMillis();
for (int i = 0; i < count; i++) benchmark();
long stopTime = System.currentTimeMillis();
return stopTime - startTime;
}
}
}
在上例中,我们希望重复执行benchmark()操作,但是对benchmark()的具体内容没有说明,而是延迟到其子类中描述:
public class MethodBenchmark extends Benchmark
{
/**
* 真正定义benchmark内容
行注释/销注释 Ctrl+/ 块注释/销注释 Ctrl+Shift+/ Ctrl+Shift+/ 查找 查找替换 Ctrl+H Ctrl+F 查找下一个/往回找 Ctrl+K Ctrl+Shift+K 跳到某行 Ctrl+L,哈用惯了Editplus,不时会敲下Ctrl+G, 查找当前元素的声明 Ctrl+G 查找当前元素的所有引用 Ctrl+Shift+G 重新组织Import Ctrl+Shift+O,能帮你一次去掉所有未使用的Import声明! 快速修正 Ctrl+1 引入某个类(接口)ctrl + shift + m 加头注释 shift + alt + j ctrl + shift + g:查看引用 ctrl + shift + n:重命名 ctrl + shift + o:导入类 ctrl + shift + r:启动上次运行 ctrl + shift + f:格式化代码 ctrl + c:复制 ctrl + v:粘贴 ctrl + x:切剪 ctrl + a:全选 ctrl + f:查找 ctrl + z:撤销 ctrl + y:重做 ctrl + s:保存 --------------------------------------------------------------- 用的最多的应该就是CTRL+SHIFT+S 还有格式化用的也挺多。 --------------------------------------------------------------- ctrl + shift + f 格式化代码 ctrl + shift + o 组织导入 F3 打开声明 Alt + shift + r 重命名变量 --------------------------------------------------------------- up --------------------------------------------------------------- Alt+/ --------------------------------------------------------------- alt + left alt + right ctrl + q --------------------------------------------------------------- ctrl + shift + g:查看引用 ctrl + shift + n:重命名 ctrl + shift + f:格式化代码 ctrl + c:复制 ctrl + v:粘贴 ctrl + a:全选 ctrl + f:查找 ctrl + z:撤销 ctrl + s:保存 Alt + / 智能提示 --------------------------------------------------------------- ctrl + shift + g:查看引用 ctrl + shift + n:重命名 ctrl + shift + o:导入类 ctrl + shift + r:启动上次运行 ctrl + shift + f:格式化代码 ctrl + c:复制 ctrl + v:粘贴 ctrl + x:切剪 ctrl + a:全选 ctrl + f:查找 ctrl + z:撤销 ctrl + y:重做 ctrl + s:保存 Alt + / 智能提示 F3 打开声明 Alt + shift + r 重命名变量 其实最常用的就是下面几个: ctrl + shift + o:导入类 ctrl + shift + f:格式化代码 ctrl + c:复制 ctrl + v:粘贴 ctrl + x:切剪 ctrl + z:撤销 ctrl + s:保存 Alt + / 智能提示 --------------------------------------------------------------- Ctrl+M: 工作区最大化/最小化 Alt+/: 智能提示 F3: 察看声明 Crtl+1: 修正错误 Shift+Alt+T: 重构 Shift+Alt+M: 提取函数 Shift+Alt+R: 重命名 Shift+Alt+C: 更改函数标记 Ctrl+Shitf+F: 格式化代码 --------------------------------------------------------------- ctrl + shift + o:导入类 atl + /:提示 ctrl + shift + t:查找相关信息 --------------------------------------------------------------- Eclipse快捷键指南 编辑 作用域 功能 快捷键 全局 查找并替换 Ctrl+F 文本编辑器 查找上一个 Ctrl+Shift+K 文本编辑器 查找下一个 Ctrl+K 全局 撤销 Ctrl+Z 全局 复制 Ctrl+C 全局 恢复上一个选择 Alt+Shift+↓ 全局 剪切 Ctrl+X 全局 快速修正 Ctrl1+1 全局 内容辅助 Alt+/ 全局 全部选中 Ctrl+A 全局 删除 Delete 全局 上下文信息 Alt+? Alt+Shift+?
string strConn = " uid=账号;pwd=密码;database=数据库;server=服务器 " ; // SQL Server链接字符串 SqlConnection ConnSql = new SqlConnection (strConn); // Sql链接类的实例化 ConnSql.Open (); // 打开数据库 string strSQL = " SELECT * FROM 表名1 " ; // 要执行的SQL语句 SqlDataAdapter da = new SqlDataAdapter(strSQL,ConnSql); // 创建DataAdapter数据适配器实例 DataSet ds = new DataSet(); // 创建DataSet实例 da.Fill(ds, " 自定义虚拟表名 " ); // 使用DataAdapter的Fill方法(填充),调用SELECT命令 ConnSql.Close (); // 关闭数据库 转载于:https://www.cnblogs.com/qiangshu/archive/2009/12/15/1624467.html
--上月的第一天 SELECT CONVERT(CHAR(10),DATEADD(month,-1,DATEADD(dd,-DAY(GETDATE())+1,GETDATE())),111) SELECT DATEADD(mm,DATEDIFF(mm,0,dateadd(month,-1,getdate())),0) --上月的最后一天 SELECT CONVERT(CHAR(10),DATEADD(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()),0)),111)+' 23:59:59' select dateadd(ms,-3,DATEADD(mm,DATEDIFF(mm,0,getdate()),0)) --本月的第一天 SELECT CONVERT(CHAR(10),DATEADD(dd,-DAY(GETDATE())+1,GETDATE()),111) SELECT CONVERT(datetime,CONVERT(char(8),GETDATE(),120)+'1') --本月的最后一天 SELECT CONVERT(CHAR(10),DATEADD(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate())+1,0)),111)+' 23:59:59' select DATEADD(d,-day(getdate()),dateadd(m,1,getdate())) --下个月的最后第一天 SELECT CONVERT(CHAR(10),DATEADD(m,1,DATEADD(dd,-DAY(GETDATE())+1,GETDATE())),111) --下月的最后一天 SELECT CONVERT(CHAR(10),DATEADD(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate())+2,0)),111)+' 23:59:59' --获取当天的最后一刻 select DATEADD(SS,-1,dateadd(day,1,CONVERT(varchar(15) , getdate(), 102 ))) 转载于:https://www.cnblogs.com/qiangshu/p/5453155.html
实现为对话框程序添加状态栏主要步骤如下:
1. 在资源的String table添加两个字符串资源
资源ID 资源值
IDS_PANEL1 第一个Panel
IDS_PANEL2 第二个Panel
2. 在对话框类中加入CStatusBar成员变量
CStatusBar m_wndStatusBar;
3. 在StdAfx.h文件里定义如下分割数组
static UINT indicators[] =
{
IDS_PANEL1,
IDS_PANEL2,
};
4. OnInitDialog里创建并显示状态栏
CRect rect; GetClientRect(rect); //状态条 if (!m_wndStatusBar.Create(this)|| !m_wndStatusBar.SetIndicators( indicators,sizeof(indicators)/sizeof(UINT))) { TRACE0("创建状态栏失败\n"); return -1; // 未能创建 } m_wndStatusBar.MoveWindow(0, rect.bottom-20, rect.right, 20 ); 转载于:https://www.cnblogs.com/rogee/archive/2011/02/15/1954990.html
引言 目前,不少流行软件都提供有对外挂插件的支持功能,如Winamp、Realplay等等。这些软件通过对插件技术的使用为日后的软件升级和功能扩展提供了相当的便利条件。 尤为重要的是,通过使用插件技术,使得对软件的功能扩展将不再完全受限于软件厂商,任何第三方开发商或是程序员个人只要遵循了软件提供的插件接口标准去开发插件就完全可以同主体软件有很好的兼容,从而使用户对应用程序进行个性化功能扩展成为了可能。基于插件技术的以上诸多优势,本文下面将围绕插件的制作、应用程序对插件的支持等具体问题对其展开讨论。
设计思路及插件接口标准
通常支持插件的应用程序多将外挂扩展插件集中放置于某个指定的目录下,程序执行时首先在此目录下搜寻是否有插件存在,如有则为插件将其插入到应用程序,应用程序在终止运行时负责将插件释放。
至于插件以何种形式提供则没有固定的规定,可以是独立的应用程序,也可以是动态链接库或是其他一些文件格式,不管插件具体以何种形式提供,都是以方便使用为目的。本文即以使用较为灵活的动态链接库作为插件的提供形式,动态链接库通过外部导出函数为应用程序提供对插件功能的调用,应用程序在对动态链接库进行动态装载时也比较容易实现。这里与以往对动态链接库的使用有所不同,通常的应用程序事先已经明确知道需要使用哪些动态链接库,动态链接库又提供有哪些函数等信息,而允许使用插件的应用程序在发布时则无法预知在软件发布后第三方开发商将会开发出多少插件、插件都提供有什么功能函数等。因此这就需要在容许插件的应用程序和插件之间建立一种统一的接口标准并通过此接口标准完成对所有后期插件的管理。在此,主程序和插件之间是通过一个标准的DLL导出函数来实现的,主要用于在主体程序内插件对象的创建:
BOOL Plug_CreateObject(void ** pobj)
{
*pobj = new CPlugA;
return *pobj != NULL;
}
其中类CPlugA是在动态链接库中由基类CPlugBase派生出来的,提供有插件的大部分主要功能,如插件图标的获取、插件提供的功能接口函数以及插件的释放等。基类CPlugBase的结构如下:
class CPlugBase { public: CPlugBase(){}; virtual HICON GetIcon() = 0; virtual void Interface(int k) = 0; virtual void Release() = 0; }; 考虑到主体程序无法预知待插入的插件数目,为管理插件对象方便, 通过模板类CArray完成对各个插件对象的存储与管理,此模板类所管理的数组为PLUG_ST结构对象。PLUG_ST结构记录了插件类提供的的CPlugBase型指针和作为插件载体的动态链接库的实例句柄,其具体定义如下:
typedef struct{
CPlugBase * pObj;
HINSTANCE hIns;
}PLUG_ST, * LPPLUG_ST;
另外,在程序界面上,每向应用程序添加一个新的插件,都应当在主程序的界面上增添与之相关联的按钮或菜单等,以便用户可以通过位于主程序界面上的按钮或菜单实现对插件内部功能函数的调用。本文在此是通过向工具条增添按钮的方式来达到此目的的,按钮上的图标由插件提供,应用程序通过插件类的GetIcon()函数获取到图标句柄,并将其绘制在工具条按钮上。
为普通应用程序扩展插件支持功能
插件支持功能并非Winamp、RealPlay等大牌软件所独有,任何普通应用程序经过程序编码均可将其扩展为支持插件的应用程序。通常将这部分扩展代码在主框架类中完成,根据前面所述思路,首先从应用程序所在目录下搜寻子目录PLUGINS下是否存在以动态链接库形式提供的插件,如果在此目录下没有找到动态链接库那么就说明当前还没有插件,因此程序也就不需要做进一步处理,如果找到插件,就一一将其插入到应用程序。搜寻插件的部分代码如下:
…… GetModuleFileName(NULL, filename, MAX_PATH); // 获取应用程序路径 strPath = CString(filename); //设定当前目录下的子目录PLUGINS strPath = strPath.
/***************code.h********************/ #ifndef _CODE_H_ #define _CODE_H_ #include <string> using namespace std; class CCode { public: string Encode(const string & str); string Decode(const string & str); }; #endif /*****************code.cpp*************************/ #include “code.h” string CCode::Encode(const string & str) { string ret=”"; char buf[20]; int i=0; while(i<str.length()) { if(str[i] & 0×80) { sprintf(buf,”%%%1X%1X”,(unsigned char)str[i],(unsigned char)str[i+1]); ++i; ret+=buf; } else ret+=str[i]; ++i; } return ret; } string CCode::Decode(const string & str) { string ret=”"; string cur,all=str; while(all.
都是DC嘛,HDC就是最原始的 DC 句柄,很多API的第一个参数就是一个HDC类型,比如 HDC hDC = ::GetDC( m_hWnd); ::MoveToEx( hDC, 0,0, NULL ); ::LineTo( hDC, 0, 100, ); ::ReleaseDC( m_hWnd, hDC ); 在MFC中,为了将API封装成一个类来操作,因此多出来了一个CDC。所以在MFC中,都是 CDC dc = GetDC(); dc.MoveTo( 0,0 ); dc.LineTo( 0,100 ); this->ReleaseDC( &dc ); 但这样还不够,因为 CDC还要你自己去释放,所有MFC中又多出来一个CClientDC, 这样你就可以这样了: CClientDC dc(this); dc.MoveTo( 0,0 ); dc.LineTo( 0,100 ); CClientDC的析构函数自己会释放自己。 DC不是什么对象,就是设备上下文的简称。 与CClientDC一样,还有CWindowDC,CPaintDC,只是它们的绘制范围不一样。 但弄到底,都只是HDC的一些封装而已,你可以在CDC类中直接引用 m_hDC,这就是那个原始的HDC句柄了。 转载于:https://www.cnblogs.com/rogee/archive/2011/04/02/2003109.html
在开发程序过程中,有许多情况中都需要执行程序自己把自己从物理磁盘上删除,例如,卸装程序,一些黑客程序获取信息后自清除等,我们把这些具有自删除功能的程序统称为“自杀”程序。对于一名程序员,想必都有在程序中使用代码删除物理磁盘文件的经历吧,我们只需要简单的调用DeleteFile API函数就可以搞定,但是该函数并不能删除自己,当它执行删除自己时,将会导致出现“无法删除文件:拒绝访问。源文件可能正被使用”的错误提示,其原因是由于本程序在执行删除自己代码时仍处于内存中,在Windows中,不可以删除正在执行中的程序。 为了实现程序自删除功能,我们可以通过多进程的方法解决这个问题。可执行文件在结束返回前,创建一个运行命令窗口的新进程(在Windows98中为Command进程,在Windows2000/XP中为CMD进程),当然该命令窗口以隐藏方式执行,并通过传递参数执行删除功能。为了避免可执行文件的映像还在内存中就执行删除,需要把当前进程设置为实时优先级,而命令窗口进程设置为很低的IDLE优先级,这样首先可执行文件结束返回,再运行命令窗口的删除命令,就实现了该文件自身的删除功能。 下面我们就一起动手制作“自杀”(具有自删除功能)程序,程序在Visual C++6.0中开发编译。 首先,启动Visual C++6.0,新建一个MFC AppWizard(exe)类型的项目,项目名为SelfDelete,选择基于对话框模式创建程序框架。 接下来,打开资源编辑器,添加一个按钮控件,设置内容为开始“自杀”,如图一所示: 启动ClassWizard,为新添加的控件新建CLICK事件处理函数,再打开该函数,添加“自杀”代码如下: void CSelfDeleteDlg::OnButton1() { // TODO: Add your control notification handler code here SHELLEXECUTEINFO sei; TCHAR szModule [MAX_PATH],szComspec[MAX_PATH],szParams [MAX_PATH]; //获取文件路径名 if((GetModuleFileName(0,szModule,MAX_PATH)!=0) && (GetShortPathName(szModule,szModule,MAX_PATH)!=0) && (GetEnvironmentVariable("COMSPEC",szComspec,MAX_PATH)!=0)) { //设置命令行参数。 lstrcpy(szParams,"/c del "); lstrcat(szParams, szModule); lstrcat(szParams, " > nul"); //初始化SHELLEXECUTEINFO结构成员 sei.cbSize = sizeof(sei); //设置类型大小。 //命令窗口进程句柄,ShellExecuteEx函数执行时设置。 sei.hwnd = 0; sei.lpVerb = "Open"; //执行动作为“打开执行”。 sei.lpFile = szComspec; //执行程序文件全路径名称。 sei.lpParameters = szParams; //执行参数。 sei.lpDirectory = 0; //显示方式,此处使用隐藏方式阻止出现命令窗口界面。 sei.
WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。
1. WinDbg介绍:
Debugging Tools and Symbols: Getting Started
http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
A word for WinDbg
http://mtaulty.com/communityserver/blogs/mike_taultys_blog/archive/2004/08/03/4656.aspx
2. WinDbg下载:
Install Debugging Tools for Windows 32-bit Version
http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
Install Debugging Tools for Windows 64-bit Versions
http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx
3. 配置WinDbg:
运行WinDbg->菜单->File->Symbol File Path->按照下面的方法设置_NT_SYMBOL_PATH变量:
在弹出的框中输入“C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照这样设置,WinDbg将先从本地文件夹C:\MyCodesSymbols中查找Symbol,如果找不到,则自动从MS的Symbol Server上下载Symbols)。另一种做法是从这个Symbol下载地址中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下载相应操作系统所需要的完整的Symbol安装包,并进行安装,例如我将其安装在D:\WINDOWS\Symbols,在该框中输入“D:\WINDOWS\Symbols”。(这里要注意下载的Symbols的版本一定要正确,在我的Win2003+Sp1上,我曾经以为安装Win2003+Sp2的Symbols可能会牛×点,但结果证明我错了,用WinDbg打开可执行文件时,提示“PDB symbol for mscorwks.dll not loaded;Defaulted to export symbols for ntdll.dll”的错误,我有重新装上Win2003+Sp1的Symbols, 现在一切运行正常^_^)
4. 使用WinDbg:
WinDbg提供了图形界面和命令行两种运行方式。这里介绍使用图形界面的WinDbg来调试应用程序:
File->OpenExecutable->可以选择一个可执行文件进行调试;
File->Attache to a Process->可以选择一个运行中的进程,并对其进行调试;
至此,我们就可以在上图中用红色方框标记的文本框中输入各个功能指令了(有关指令的帮助文档,可以参考:Help->Contents->Debugging Tools for Windows->Debuggers->Debugger Reference,该目录下列集了所有指令机器功能说明!)。 转载于:https://www.cnblogs.com/happyhippy/archive/2007/04/08/710933.html
This article is for Visual Studio 2005.
Step 1. steup your [TestFixture] and [Test]. And open the dll file from NUnit-GUI.
The detail of Step 1 is shown here: http://www.tangent-studios.com/programming/csharp/NUnit2Tut/NUnitV2Tut.htm
This is a small and easy tutorial, just spend your 5 mintues.
Step 2. Add breakpoint into your NUnit [TestFixture] class in Visual Studio.net 2005.
Step 3. Click "Run" in NUnit.
Step 4. Click Debug-->Attach To Process Select 'nunit-gui.exe" from "
1.展示世界的總人口。
SELECT sum(population) FROM world 2.列出所有的洲份, 每個只有一次。
SELECT DISTINCT continent FROM world 3.找出非洲(Africa)的GDP總和。
SELECT SUM(gdp) FROM world WHERE continent = 'Africa' 4.有多少個國家具有至少百萬(1000000)的面積。
SELECT COUNT(name) FROM world WHERE area > 1000000 5.('France','Germany','Spain')(“法國”,“德國”,“西班牙”)的總人口是多少?
SELECT SUM(population) FROM world WHERE name IN ( 'France','Germany','Spain') 6.對於每一個洲份,顯示洲份和國家的數量。
SELECT continent, COUNT(name) FROM world GROUP BY continent 7.對於每一個洲份,顯示洲份和至少有1000萬人(10,000,000)口國家的數目。
SELECT continent, COUNT(name) FROM world WHERE population > 10000000 GROUP BY continent 8.列出有至少100百萬(1億)(100,000,000)人口的洲份。
SELECT continent FROM world GROUP BY continent HAVING SUM(population) > 100000000