GetCurrentProcess():
GetCurrentProcess得到得到的称之为"伪句柄"
只是一个标识,你可以发现,其实就是返回$FFFFFFFF,
每个进程得句柄都是一样得,只是实用于进程内部得使用.
如果你想得到实际得句柄,在进程间进行通讯,必需要进行转化,
调用DuplicateHandle,注意,得实句柄使用完成以后,你必须要调用CloseHandle去关闭.
其实,你应该明白了为何"伪句柄"得存在,就是使用简单,不用关闭,
不会造成内存泄漏.
同样道理,GetCurrentThread也是伪句柄,其值永远是$FFFFFFFE,只是适用于线程内部得使用.
DuplicateHandle() :
在系统中,对象分两类:核心对象和用户对象.如进程对象,线程对象,文件映射
对象等就是核心对象;而向窗口,菜单等都是用户对象.
两者是有差别的,用于标示用户对象的句柄是系统唯一的,也就是说,一个进程
完全可以对另外一个进程中的用户对象进行操作,比如两个进程间通信的方法之一,
就是发送消息.正是由于窗口是用户对象,所以句柄是系统唯一,通过FindWindow(),
得到另外一个进程的窗口句柄,然后用SendMessage(),让hWnd的窗口过程来处理消
息,实现了进程间的通信.因此,对于用户对象,你根本不用DuplicateHandle(),直接
把句柄拿来用就行了.
而核心对象则不一样.核心对象是为了加强系统的稳定性,因此,核心对象句柄是
进程相关的,在每一个进程中都有一个核心对象表,每一个对象的索引(不完全是)作为内和对象的句柄,从而实现进程相关.同一个对象在不同的进程中可能有不同的索引,即句柄.对核心对象进行操作时,系统还要进行安全检验,看一下你是否有权来操作这个对象.因此你不能同用户对象一样,直接把句柄拿过来用.比方说,你想操作另一个进程中的文件映射对象,这个文件映射对象句柄在那个进程中假设是0x000001,但在你的进程中,很有可能0x00000001时表示另一个核心对象,此时的操作就永远不会成功,甚至会产生灾难性的后果.此时,就有必要用DuplicateHandle().
ShellExecute
Q: 如何打开一个应用程序?
ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW );
或
ShellExecute(this->m_hWnd,"open","notepad.exe", "c://MyLog.log","",SW_SHOW );
正如您所看到的,我并没有传递程序的完整路径。
Q: 如何打开一个同系统程序相关连的文档?
ShellExecute(this->m_hWnd,"open", "c://abc.txt","","",SW_SHOW );
ShellExecute(this->m_hWnd,"open", "http://www.google.com","","", SW_SHOW );
ShellExecute(this->m_hWnd,"open", "mailto:nishinapp@yahoo.com","","", SW_SHOW );
ShellExecute(this->m_hWnd,"print", "c://abc.txt","","", SW_HIDE);
Q: 如何用系统查找功能来查找指定文件?
ShellExecute(m_hWnd,"find","d://nish", NULL,NULL,SW_SHOW);
Q: 如何启动一个程序,直到它运行结束?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c://MyProgram.exe";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("c://winnt//notepad.exe", NULL,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
else
{
MessageBox("The process could not be started...");
}
Q: 如何显示文件或文件夹的属性?
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c://"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
-----------------------------------------------------------------------------------------------------------------------------
转自 http://blog.youkuaiyun.com/dodream/article/details/1684446
MFC::CFileFind
1、CFileFind类的声明文件保存在afx.h头文件中。
2、该类的实现的功能:执行本地文件的查找(查找某个具体的文件,查找某类文件x*.x*,查找所有文件*.*)
3、CFileFind类是CGopherFileFind和CFtpFileFind类的基类。
4、CFileFind类的构造函数::CFileFind()和关闭函数::Close()我会成对使用。
5、CFileFind类的成员函数我根据其操作特性划分为3类:查找操作类、获得文件属性类、判断文件属性类。(下面我先进行函数罗列并没有完整的描述函数的参数)
查找操作类
::FindFile();
::FindNextFile();
获得文件属性类
::GetCreationTime();
::GetLastAccessTime();
::GetLastWriteTime();
::GetFileName();
::GetRoot();
::GetFilePath();
::GetFileTitle();
::GetFileURL();
::GetLength();
判断文件属性类
::IsArchived();
::IsCompressed();
::IsDirectory();
::IsDots();
::IsHidden();
::IsNormal();
::IsReadOnly();
::IsSystem();
::IsTemporary();
::MatchesMask();
6、CFileFind类中成员函数使用应注意的顺序
在创建了CFileFind对象后,先执行::FindFile()函数,然后执行::FindNextFile(),然后选择执行(获得文件属性类)的函数或者(判断文件属性类)函数。
7、CFileFind类成员函数的详细分析
virtual BOOL FindFile(LPCTSTR pstrName = null,DWORD dwUnused = 0);
该函数若返回非0 则表明执行成功,0 则表明执行不成功。
pstrName:需要查找的文件名,例:“E://编程工具//VC++//MFC例子.rar”,“E://编程工具//VC++//MFC*.rar”,“E://编程工具//VC++//*.*”,也可以是NULL表示“*.*”。
dwUnused:必须为0
virtual BOOL FindNextFile();
该函数返回值非0 还有符合条件的文件, 0表示是最后一个文件。
virtual BOOL GetCreationTime(FILETIME *pFileTime) const;
virtual BOOL GetCreationTime(CTime& refTime) const;
该函数用来获得查找到的某个文件的创建时间,返回值非0 获得创建时间成功操作,0表示执行获得创建时间失败或者FindNextFile()没有被执行的时候。
FILETIME *:容纳时间的结构指针
CTime&:容纳时间的对象地址
此处介绍:FILETIME和CTime相互转换的处理方法:
FILETIME转CTime的方法:
A、CTime对象在初始化时可以传递FILETIME结构
FILETIME ft;
CTime time(ft);
B、将FILETIME转换为SYSTEMTIME,然后CTime对象在初始化时可以传递SYSTEMTIME结构
FILETIME ft;
SYSTEMTIME st;
BOOL bSuccess = ::FileTimeToSystemTime(&ft , &st);
CTime time(st);
CTime转FILETIME方法:
CTime time(CTime::GetCurrentTime());
SYSTEMTIME st;
time.GetAsSystemTime(st);
FILETIME ft;
::SystemTimeToFileTime(&st,&ft);
virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;
virtual BOOL GetLastAccessTime(CTime& refTime) const;
该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。
virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;
virtual BOOL GetLastWriteTime(CTime& refTime) const;
该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。
virtual CString GetFilePath() const;
该函数用来获得查找到的文件绝对路径,必须在执行了FindNextFile()后该函数才能执行成功。
返回的结果是CString对象,例“E://编程工具//VC++//MFC.rar”
virtual CString GetFileName() const;
该函数用来获得查找到的文件的全称,必须在执行了FindNextFile()后该函数才能执行成功。
返回的结果是CString对象,例“MFC.rar”
virtual CString GetFileTitle() const;
该函数用来获得查找到的文件的名称,必须在执行了FindNextFile()后该函数才能执行成功。
返回的结果是CString对象,例“MFC”
virtual CString GetRoot() const;
该函数用来获得查找到的文件的根目录,必须在执行了FindNextFile()后该函数才能执行成功。
返回的结果是CString对象,例“E://编程工具//VC++//”
virtual CString GetFileURL() const;
该函数用来获得查找到的文件的URL路径,必须在执行了FindNextFile()后该函数才能执行成功。
返回的结果是CString对象,例“file://E://编程工具//VC++//MFC.rar”
DWORD GetLength() const;
该函数返回值获得查找到的文件的长度,必须在执行了FindNextFile()后该函数才能执行成功。
BOOL IsArchived() const;
该函数用来判断查找的文件属性是否是档案文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsCompressed() const;
该函数用来判断查找的文件属性是否是压缩文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsDirectory() const;
该函数用来判断查找的文件属性是否是路径文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsDots() const;
该函数用来判断查找的文件属性是否是“.”,“..”,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsHidden() const;
该函数用来判断查找的文件属性是否隐藏文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsNormal() const;
该函数用来判断查找的文件属性是否正常文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsReadOnly() const;
该函数用来判断查找的文件属性是否只读文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsSystem() const;
该函数用来判断查找的文件属性是否系统文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsTemporary() const;
该函数用来判断查找的文件属性是否临时文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL MatchesMask(DWORD dwMask) const;
---------------------------------------------------------------------------------------------------------
该函数用来判断查找的文件的综合属性,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
dwMask参数的使用方法:几种文件属性采用或运算(|)
文件属性的结构定义:
FILE_ATTRIBUTE_ARCHIVE:档案文件
FILE_ATTRIBUTE_COMPRESSED:压缩文件
FILE_ATTRIBUTE_DIRECTORY:路径文件
FILE_ATTRIBUTE_NORMAL:正常文件
FILE_ATTRIBUTE_READONLY:只读文件
FILE_ATTRIBUTE_SYSTEM:系统文件
FILE_ATTRIBUTE_TEMPORARY:临时文件
FILE_ATTRIBUTE_HIDDEN:隐藏文件
OutputDebugString()
本文首先是由以下事件促使的,我们观察到 OutputDebugString() 在管理员和非管理员用户试图一起工作或游戏时并不总是能可靠地工作(至少在 Win2000 上)。我们怀疑是一些相关的内核对象的权限问题,此间涉略了相当多不得不写下来的信息。
请注意,尽管我们使用了“调试器”这一术语,但不是从调试 API 的意义上来使用的:并没有“单步执行”、“断点”或者“附着到进程”等可以在 MS Visual C 或者一些真正的交互开发环境中找到的东西。从某种意义上来说,任何实现了协议的程序都是“调试器”。可能是一个非常小的命令行工具,或者像来自于 SysInternals 那帮聪明的家伙们的 DebugView 那样的高级货。
内容目录
应用程序用法
<windows.h> 文件声明了 OutputDebugString() 函数的两个版本 - 一个用于 ASCII,一个用于 Unicode - 不像绝大多数 Win32 API 一样,原始版本是 ASCII。而大多数的 Win32 API 的原始版本是 Unicode。
使用一个 NULL 结尾的字符串缓冲区简单调用 OutputDebugString() 将导致信息出现在调试器中,如果有调试器的话。构建一条信息并发送之的通常用法是:
sprintf(msgbuf, "Cannot open file %s [err=%ld]/n", fname, GetLastError()); OutputDebugString(msgbuf);
不过在实际环境中我们中的不少人会创建一个前端函数,以允许我们使用 printf 风格的格式化。下面的 odprintf() 函数格式化字符串,确保结尾有一个合适的回车换行(删除原来的行结尾),并且发送信息到调试器。
#include <stdio.h> #include <stdarg.h> #include <ctype.h> void __cdecl odprintf(const char *format, ...) { char buf[4096], *p = buf; va_list args; va_start(args, format); p += _vsnprintf(p, sizeof buf - 1, format, args); va_end(args); while ( p > buf && isspace(p[-1]) ) *--p = '/0'; *p++ = '/r'; *p++ = '/n'; *p = '/0'; OutputDebugString(buf); }
于是在代码中使用它就很简单:
... odprintf("Cannot open file %s [err=%ld]", fname, GetLastError()); ...
我们已经这样使用多年了。
---------------------------------------------------------------------------------------------------------