c语言osversioninfoex,xi52qian

头文件

一. 对终端的操作

相关头文件#include

1. 输入istream

2. 输出ostream

3. iostream继承istream和ostream 所以它具有输入输出功能。

为了方便这个库定义了下列三个标准流对象:

1. cin  代表标准输入istream类对象一般地cin使我们能够从用户终端读入数据。

2. cout 代表标准输出ostream类对象一般地cout使我们能够向用户终端写数据。

3. cerr 代表标准错误ostream类对象一般地cerr是导出程序错误消息的地方。

另外,输出主要由重载的左移操作符<< 来完成类似地输入主要由重载的右移操作符>>来完成。

Demo1:

#include

#include

int main() {

string in_string;

// 向用户终端写字符串

std::cout << "Please enter your name:";

// 把用户输入的读取到 in_string 中

std::cin >> in_string;

if ( in_string.empty() )

// 产生一个错误消息输出到用户终端

std::cerr << "error: input string is empty!\n";

else std::cout << "hello," << in_string << "!\n";

}

二. 对文件的操作

相关头#include

1. ifstream 从istream 派生把一个文件绑到程序上从文件读取数据用来输入。

2. ofstream 从ostream 派生把一个文件绑到程序上用来向文件写入数据。

3. fstream 从iostream 派生把一个文件绑到程序上用来输入和输出。

注:由于在fstream 头文件中也包含了iostream 头文件所以我们不需要同时包含这两个文

件C++对于文件的输入输出也支持同样的输入和输出操作符。

Demo2:

#include

#include

#include

#include

int main()

{

string ifile;

cout << "Please enter file to sort:";

cin >> ifile;

// 构造一个 ifstream 输入文件对象

ifstream infile( ifile.c_str() );

if( ! infile ) {

cerr << "error: unable to open input file:" << ifile << endl;

return -1;

}

string ofile = ifile + ".sort";

// 构造一个 ofstream 输出文件对象

ofstream outfile( ofile.c_str() );

if( !outfile ) {

cerr << "error: unable to open output file:" << ofile << endl;

return -2;

}

string buffer;

vector text;

int cnt = 1;

while ( infile >> buffer ) {

text.push_back( buffer );

cout << buffer << ( cnt++ % 8 ? "" : "\n" );

}

sort( text.begin(), text.end() );

// ok: 把排序后的词打印到 outfile

vector::iterator iter = text.begin();

for ( cnt = 1; iter != text.end(); ++iter, ++cnt )

outfile << *iter << (cnt%8 ? "" : "\n" );

return 0;

}

三. 对字符流操作

相关的头文件#include

1 istringstream 从istream 派生从一个字符串中读取数据。

2 ostringstream 从ostream 派生写入到一个字符串中。

3 stringstream 从iostream 派生从字符串中读取或者写入到字符串中。

Demo3:

#include

string program_name( "our_program" );

string version( "0.01" );

// ...

string mumble( int *array, int size )

{

if ( ! array ) {

ostringstream out_message;

out_message << "error:"

<< program_name << "--" << version

<< ":" << __FILE__ << ":" << __LINE__

<

<< "must address some array.\n";

// 返回底层 string 对象

return out_message.str();

}

四. wchar_t型

支持wchar_t类型的流读写操作

wcin wcout wcerr wiostream 等等....

20.1 输出操作符<<

1. 支持所有的内置数据类型 包括string ,const char* 和complex。以及函数的调用。

2. endl等价于输出换行操作符,然后再刷新缓存区。cout << '\n' << flush;

3. <

4. cout << p << &i << endl;会输出指针的地址(p是int *,i是int)。如果是const char * pcStr不会输出指针地址值,

输出的是字符串。转换为cout << static_cast(const_cast(pcStr));

5. <

6. ostream_iterator和cout的使用。

Demo4:

#include

#include

#include

#include

string pooh_pals[] = {

"Tigger", "Piglet", "Eeyore", "Rabbit"

};

int main()

{

vector ppals( pooh_pals, pooh_pals+4 );

vector::iterator iter = ppals.begin();

vector::iterator iter_end = ppals.end();

cout << "These are Pooh's pals:";

// 把每个元素拷贝到 cout ...

ostream_iterator< string > output( cout, "" );

copy( iter, iter_end, output );

cout << endl;

}

7. cout << 遇到‘\0’会定制输出。

20.2 输入操作符>>

1. while(cin >> 变量)的时候有两种情况会让循环停止(false):

(1) 读到文件结束在这种情况下我们已经正确地读完文件中所有的值。

(2) 遇到一个无效的值比如3.14159小数点是非法的1e-1字符文字e是非法的或者一般的任意字符串文字在读入一个无效值的

情况下istream对象被放置到一种错误的状态中并且对于值的所有读入动作都将停止。

2. 预定义的输入操作符可以接受任何的内置数据类型包括C 风格字符由以及标准库string和complex 类类型。

3. 缺省情况下输入操作符丢弃任何中间空白空格制表符换行符走纸以及回车。

Demo5:

#include

#include

int main()

{

int item_number;

string item_name;

double item_price;

cout << "Please enter the item_number, item_name, and price:" << endl;

cin >> item_number;

cin >> item_name;

cin >> item_price;

cout << "The values entered are: item#"

<< item_number << ""

<< item_name << "@$"

<< item_price << endl;

}

4. 如果希望读入空白符号可以利用cin.get()方法一个个读入,或者设置skipws和noskipws选项(后面介绍)。

5. isream_iterator和cin关联使用。

Demo6:

#include

#include

#include

#include

int main()

{

istream_iterator< string > in( cin ), eos ;

vector< string > text ;

// 从标准输入向 text 拷贝值

copy( in , eos , back_inserter( text ) ) ;

sort( text.begin() , text.end() ) ;

// 删除所有重复的值

vector< string >::iterator it ;

it = unique( text.begin() , text.end() ) ;

text.erase( it , text.end() ) ;

// 显示结果 vector

int line_cnt = 1 ;

for ( vector< string >::iterator iter = text.begin();

iter != text.end() ; ++iter , ++line_cnt )

cout << *iter

<< ( line_cnt % 9 ? "" : "\n" ) ;

cout << endl;

}

20.2.1 字符串输入

1. setw函数:防止读入字符串益处(char[4],输入4个以上字节),while ( cin >> setw( bufSize ) >> buf )

这里bufSize是字符数组buf的长度setw()把长度等于或大于bufSize 的字符串分成最大长度为bufSize - 1的两个

或多个字符串,在每个新串的末尾放一个空字符为了使用setw()要求程序包含iomanip头文件#include 。

2. 用string没有char *那些长度和内存溢出问题,更容易使用。

20.3 其他输入输出操作符

一. istream的成员get()一次读入一个字节。属于istream

1. get(char& ch)从输入流中提取一个字符包括空白字符并将它存储在ch中它返回被应用的istream对象。

与之对应的是ostream的put()方法,每次读入一个字节,然后返回ostream。

2. get()的第二个版本也从输入流读入一个字符区别是它返回该字符值而不是被应用的istream 对象它的返回类型

是int 而不是char 因为它也返回文件尾的标志end-of-file该标志通常用-1 来表示以便与字符集区分开为测试返回

值是否为文件尾我们将它与iostream 头文件中定义的常量EOF 做比较。

Demo7:

#include

int main()

{

int ch;

// 或使用:

// while (( ch = cin.get() ) && ch != EOF)

while (( ch = cin.get()) != EOF)

cout.put(ch);

return 0;

}

3. get(char *sink, streamsize size, char delimiter='\n')

(1) sink 代表一个字符数组用来存放被读取到的字符。

(2) size 代表可以从istream 中读入的字符的最大数目。

(3) delimiter 表示如果遇到它就结束读取字符的动作delimiter 字符本身不会被读入而是留在istream 中作为istream 的

下一个字符一种常见的错误是在执行第二个get()之前忘了去掉delimiter。

二. ignore( streamsize length = 1, int delim = traits::eof )函数: 属于istream

我们用istream 成员函数ignore()来去掉delimiter

缺省情况下换行符被用作delimiter。

三. gcount()函数: 属于istream

它返回由最后的get()或getline()调用实际提取的字符数。

Demo8:

#include

int main()

{

const int max_line = 1024;

char line[ max_line ];

while ( cin.get( line, max_line ))

{

// 最大读取数量 max_line - 1, 也可以为 null

int get_count = cin.gcount();

cout << "characters actually read:"

<< get_count << endl;

// 处理每一行

// 如果遇到换行符

// 在读下一行之前去掉它

if ( get_count & max_line-1 )

cin.ignore();

}

}

四. getline(char *sink, streamsize size, char delimiter='\n')属于istream

五. write( const char *sink, streamsize length )属于ostream

提供了另外一种方法可以输出字符数组”它不是输出直到终止空字符为止的所有字符“而是输出某个长度的字符序列包括内含的

空字符它的函数。length 指定要显示的字符个数write()返回当前被调用的ostream 类对象。

六. read( char* addr, streamsize size )属于istream

read()从输入流中提取size 个连续的字节并将其放在地址从addr 开始的内存中gcount()返回由最后一个read()调用提取的字

节数而read()返回当前被调用的istream 类对象。

Demo9:

#include

int main()

{

const lineSize = 1024;

int lcnt = 0; // 读入多少行

int max = -1; // 最长行的长度

char inBuf[ lineSize ];

// 读取 1024 个字符或者遇到换行符

while (cin.getline( inBuf, lineSize ))

{

// 实际读入多少字符

int readin = cin.gcount();

// 统计: 行数最长行

++lcnt;

if ( readin > max )

max = readin;

cout << "Line #" << lcnt

<< "\tChars read:" << readin << endl;

cout.write( inBuf, readin).put('\n').put('\n');

}

cout << "Total lines read:" << lcnt << endl;

cout << "Longest line read:" << max << endl;

}

七. getline( istream &is, string str, char delimiter );

这个getline()实例的行为如下读入最大数目为str::max_size-1 个字符如果输入序列超出这个限制则读操作失败

并且istream 对象被设置为错误状态否则当读到delimiter 它被从istream 中丢弃但没有被插入到string 中或遇

到文件结束符时输入结束。

八. putback( char c ); 将字符放回 iostream。

九. unget();往回重置下一个 istream 项。

十. peek(); 返回下一个字符或 EOF,但不要提取出来。

Demo10:

char ch, next, lookahead;

while ( cin.get( ch ))

{

switch (ch) {

case '/':

// 是注释行吗? 用 peek() 看一看:

// 是的? ignore() 余下的行

next = cin.peek();

if ( next == '/' )

cin.ignore( lineSize, '\n' );

break;

case '>':

// 查找 >>=

next = cin.peek();

if ( next == '>' ) {

lookahead = cin.get();

next = cin.peek();

if ( next != '=' )

cin.putback( lookahead );

}

20.4 重载输出操作符<<

输出操作符是一个双目操作符它返回一个ostream 引用重载定义的通用框架如下

// 重载 output 操作符的通用框架

ostream&

operator <

{

// 准备对象的特定逻辑

// 成员的实际输出

os << // ...

// 返回 ostream 对象

return os;

}

注:因为第一个实参是一个ostream 引用所以输出操作符必须定义为非成员函数,当输出操作符要求访问非公有成员

时必须将它声明为该类的友元。

20.5 重载输入操作符>>

1 由于不正确的格式而导致失败istream 应该把状态标记为fail。setstate( ios_base::failbit )。

2 对于错误状态中的iostream 插入和提取操作没有影响。

Demo11:

#include

#include "WordCount.h"

/* 必须修改 WordCount, 指定输入操作符为友元

class WordCount {

friend ostream& operator<

friend istream& operator>>( istream&, WordCount& );

*/

istream&

operator>>( istream &is, WordCount &wd )

{

/* WordCount 对象被读入的格式:

* <2> string

* <7,3> <12,36>

*/

int ch;

/* 读入小于符号, 如果不存在

* 则设置 istream 为失败状态并退出

*/

if ((ch = is.get()) != '

{

is.setstate( ios_base::failbit );

return is;

}

// 读入多少个

int occurs;

is >> occurs;

// 取 >; 不检查错误

while ( is && (ch = is.get()) != '>' );

is >> wd._word;

// 读入位置

// 每个位置的格式: < line, col >

for ( int ix = 0; ix < occurs; ++ix )

{

int line, col;

// 提取值

while (is && (ch = is.get())!= '

is >> line;

while (is && (ch = is.get())!= ',' );

is >> col;

while (is && (ch = is.get())!= '>' );

wd.occurList.push_back( Location( line, col ));

}

return is;

}

20.6 文件输入和输出

包含头文件#include

1. ofstream的构造函数要制定打开模式

输出模式ios_base::out 或附加模式ios_base::app 等等。在缺省情况下ostream文件以输出模式打开。

注:如果在输出模式下打开已经存在的文件则所有存储在该文件中的数据都将被丢弃如果我们希望增加而不是替换现

有文件中的数据则应该以附加模式打开文件于是新写到文件中的数据将添加到文件尾部在这两种模式下如果文件不存

在程序都会创建一个新文件。

2. 判断是否打开if (!outFile /*ofstream对象*/)

3. 因为ofstream派生于ostream,所以ofstream拥有ostream的操作,比如put()等等。

4. 自定义<

5. 用ifstream读入一个文件,派生于istream,所有拥有istream的操作,比如get()等等。

6. close()函数断开和文件的关联。

7. fstream派生于iostream,它具有对文件的读写操作。

8. seekg和seekp标记当前位置,g是在读文件中使用,p再写文件中使用。

注:第二个参数标示定位标记:

(1) ios_base::beg 文件的开始

(2) ios_base::cur 文件的当前位置

(3) ios_base::end 文件的结尾

9. tellg()或tellp()返回当前位置,g和p意义同seekg和seekp。返回值是ios_base::pos_type。

10. clear()函数:清除状态。

20.7 条件状态

一. 条件状态

1 如果一个流遇到文件结束符则eof()返回true。

2 如果试图做一个无效的操作比如seeking 重定位操作超出了文件尾则bad()返回true,一般地这表示该流由于某种

未定义的方式而被破坏了。

3 如果操作不成功比如打开一个文件流对象失败或遇到一种无效的输入格式则fail()

返回true 例如

ifstream iFile( filename, ios_base::in );

if ( iFile.fail() ) // 不能打开

error_message( ... );

4 如果其他条件都不为true 则good()返回true

二. 改变状态

1. clear()函数,状态变为显示。

2. setstate()函数,添加状态。参数设置为:

ios_base::badbit

ios_base::eofbit

ios_base::failbit

ios_base::goodbit

3. rdstate()获取成员状态,返回值ios_base::iostate。

20.8 string 流

1. 包括头文件#include

2. str()返回与ostringstream 类对象相关联的string 对象。

20.9 格式状态

操 作 符                    含 义

boolalpha               把true 和false 表示为字符串

*noboolalpha            把true 和false 表示为0 1

showbase                产生前缀指示数值的进制基数

*noshowbase             不产生进制基数前缀

showpoint               总是显示小数点

*noshowpoint            只有当小数部分存在时才显示小数点

Showpos                 在非负数值中显示+

*noshowpos              在非负数值中不显示+

*skipws                 输入操作符跳过空白字符

noskipws                输入操作符不跳过空白字符

uppercase               在十六进制下显示0X 科学计数法中显示E

*nouppercase            在十六进制下显示0x 科学计数法中显示e

*dec                    以十进制显示

hex                     以十六进制显示

oct                     以八进制显示

left                    将填充字符加到数值的右边

right                   将填充字符加到数值的左边

Internal                将填充字符加到符号和数值的中间

*fixed                  以小数形式显示浮点数

scientific              以科学计数法形式显示浮点数

flush                   刷新ostream 缓冲区

ends                    插入空字符然后刷新ostream 缓冲区

endl                    插入换行符然后刷新ostream 缓冲区

ws                      吃掉 空白字符

// 以下这些要求 #include

setfill(ch)            用ch 填充空白字符

setprecision(n)        将浮点精度设置为n

setw(w)                按照w 个字符来读或者写数值

setbase(b)             以进制基数b 输出整数值

注*表示缺省的流状态

20.10 强类型库

iostream库是强类型的例如试图从一个ostream 读数据或者写数据到一个istream都会在编译时刻被捕获到并标记为类型违例。

posted @ 2011-03-03 08:37 xi52qian 阅读(222) | 评论 (0) | 编辑 收藏

3.1 什么是内核对象

内核对象就是内核中的一块内存,是一个结构,并且只能由内核对象访问,应用程序只能通过调用Windows提供的函数来操作内核对象。每个内核对象都有相同的部分比如安全属性和使用计数器。

3.1.1 内核对象的使用计数

内核对象中的使用计数和进程无关,当进程第一次创建某个内核对象时候使用计数变为1,当另一个进程也调用此内核对象时计数变为2。当进程释放时或者关闭内核对象时(CloseHandle),内核的使用计数减去1,如果使用计数不为0的话,内核不会释放此内核对象。

3.2.2 安全性

内核对象能够得到安全描述符的保护,安全描述符定义了谁能够创建,访问和使用该对象,一般在服务器代码中使用,客户端可以忽略。

所有创建内核对象的函数的参数都有一个指向SECURITY_ATTRIBUTES结构的指针。typedef struct _SECURITY_ATTRIBUTES {

DWORD nLength;

LPVOID lpSecurityDescriptor;

BOOL bInheritHandle;

} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;只有lpSecurityDescriptor成员和安全属性有关。一般此参数传递NULL,表示默认的安全描述。如果需要:

SECURITY_ATTRIBUTES sa;

sa.nLength = sizeof(sa);

sa.lpSecurityDescriptor = NULL;

sa.bInheritHandle = FALSE;

HANDLE h = CreateMutex(&sa, FALSE, "XI");

其余进程可用用OpenMutex函数打开,如果权限可以就返回句柄,如果失败返回NULL,GetLastError被设置为ERROR_ACCESS_DENIED。

Windows除了内核对象之外还有GDI和用户对象,区分它们的简单办法就是,创建函数中带有安全描述符参数的就是内核对象。

3.2 进程的内核对象句柄表

索引                         内核对象内存块得指针                             访问屏蔽(标志位的DWORD)                      标志(标志位的DWORD)

1                               0x????????                                                0x????????                                                        0x????????

2                               0x????????                                                0x????????                                                        0x????????

…                               …                                                               …                                                                       …

3.2.1 创建内核对象

调用Create&函数族来创建相应的内核对象,返回的是内核对象的句柄(也有个说法就是句柄表的索引),如果创建失败一般会返回0(NULL),也有的会返回INVALID_HANDLE_VALUE=-1,比如CreateFile失败后会返回后者,失败的原因有可能是内存不足或者是安全问题等等。其他对内核操作的函数都需要此句柄值作为参数传递进去,如果传递一个无效的句柄进去,那么GetLastError函数的值将被置为6(ERROR_INVALID_HANDLE)。

3.2.2 关闭内核对象

BOOL CloseHandle(HANDLE hobj);

调用此函数,系统会了清理进程的句柄表中的对应项目,如果使用计数器为0,内核释放该内核对象的资源,如果使用计数器不为0,说明其他进程还在使用此内核对象,则不释放资源。

当进程忘记调用CloseHandle函数,可能造成内存泄露,但是当进程结束的时候资源一样会被释放。

如果传递的参数无效,则函数返回FALSE,并且GetLastError函数的值被设置成ERROR_INVALID_HANDLE。如果是DEBUG阶段,则返回错误信息。

3.3 跨越进程边界共享内核对象

3.3.1 对象句柄的继承性

在父进程创建子进程的时候,将参数SECURITY_ATTRIBUTES结构的Inherithandle字段设置为TRUE的话,再父进程句柄表中标示该内核对象的项的标志位的值将会变成TRUE,标示该内核对象是可以让子进程继承的,具有可继承性(仅仅标示 该句柄值具有可继承性,而内核对象没有可继承性)。

将CreateProcess的参数bInherithandle参数的值设置为TRUE,标示创建的进程可以继承有继承性的父进程句柄。

子进程创建后不会先加载程序,它先搜索父进程的句柄表将有继承性的项目原封不动的拷贝给自己(索引也没有变,所以句柄值也不变)。

父进程可以有3种方式将句柄值传递给子进程,参数传递,进程间通信和环境变量(GetEnvironmentVariavle函数解析)。BOOL

WINAPI

CreateProcess(

__in_opt LPCSTR lpApplicationName,

__inout_opt LPSTR lpCommandLine,

__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,

__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,

__in BOOL bInheritHandles,

__in DWORD dwCreationFlags,

__in_opt LPVOID lpEnvironment,

__in_opt LPCSTR lpCurrentDirectory,

__in LPSTARTUPINFOA lpStartupInfo,

__out LPPROCESS_INFORMATION lpProcessInformation

);注意:子进程再创建其子进程,如果满足上面方式,可以继续继承。如果父进程再创建子进程后,再创建句柄,子进程不会被继承。3.3.2 改变句柄标志

BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags);

改变句柄的标志,目前可改变的标志有两种

#define HANDLE_FLAG_INHERIT   0x00000001  // 继承标志

#define HANDLE_FLAG_PROJECT_FROM_CLOSE   0x00000001 // 保护不允许关闭句柄标志

可以用OR操作同时设置2个标志。第一个参数是要设置的句柄值,第二个就是要改变的标志,第三个参数是将标志改编成什么值。

BOOL GetHandleInformation(HANDLE hObkect, PDWORD pdwFlags);

获取当前句柄的标志的值。

// 设置句柄值可继承:

SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);

// 设置句柄不可继承:

SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, 0);

// 设置句柄值不可关闭,受保护:

SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, HANDLE_FLAG_PROJECT_FROM_CLOSE);

// 设置句柄值可关闭,不受保护:

SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, 0);

3.3.3 命名对象

创建内核对象函数族Create&中的最后一个参数是pszName,该参数是如果传递NULL,表示是匿名内核对象,可以通过其他俩种方式来使用其他进程的内核对象。当pszName参数传递以’\0’(最多长度为MAX_PATH 260字符)结尾的字符串时,表示启用命名对象,比如进程A调用CreateMutex(NULL, FALSE, “XI”)的时候,他将创建内核对象名字为“XI”,之后某一时刻如果进程B也调用CreateMutex(NULL, FALSE, “XI”)函数他将经过以下几步:

判断内核对象名称是否相同。

判断内核对象类型是否相同,如果名字相同但是类型不相同则Create&函数族返回NULL,GetLastError函数值为6(ERROR_INVALID_HANDLE)。

判断安全性,返回同2步,GetLastError值同2步。

如果验证通过则返回句柄(返回句柄的值和该内核对象其他句柄的值不一定相同),GetLastError的值等于ERROR_ALREADY_EXISTS。

也可以用Open&函数族来打开已经创建的句柄,成功后GetLastError也不会被设置。具体如下

HANDLE Open&(DWORD, BOOL, PCSTR);

第一个参数:表示访问权限。

第二个参数:表示新创建的句柄是否有继承性(注意不是内核对象!)。

第三个参数:不能传递NULL。如果该句柄不存在则返回NULL,GetLastError被设置为2(ERROR_FILE_NOT_FOUND)。

3.3.4 终端服务器的名字空间

Globad,Local,Session程序保留关键字,具体的没弄明白,理解的就是说当服务器的时候,客户端可以访问以这些名字开头的内核对象。

3.3.5 复制对象句柄

BOOL DuplicateHandle(

HANDLE hSourceProcessHandle,

HANDLE hSourceHandle,

HANDLE TargetProcessHandle,

PHANDLE phTargetHandle,

DWORD dwDesiredAccess,

BOOL bInheritHandle,

DWORD dwOptions);

执行DuplicateHandle函数的进程为ProcessC,原进程为ProcessS,目标进程为ProcessT。则hSourceProcessHandle为进程ProcessS的进程句柄,TargetProcessHandle为进程ProcessT的进程句柄,ProcessC将句柄hSourceHandle从ProcessC拷贝到ProcessT中,值存在phTargetHandle中,dwDesiredAccess新句柄的反问权限,bInheritHandle新句柄的继承性,参数dwOptions有两种类型分别是:

DUPLICATE_SAME_ACCESS忽略参数dwDesiredAccess,新句柄和原进程句柄具有相同的反问权限。

DUPLICATE_CLOSE_SOURCE关闭ProcessS中的拷贝句柄,内核对象的计数不变。

HANDLE hObjProcessS = CreateMutex(NULL, FALSE, NULL);

HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessIdT);

HANDLE hObjProcessT;

DuplicateHandle(GetCurrentProcess(), hObjProcessS, hProcessT , &hObjProcessT, 0, FALSE, DUPLICATE_SAME_ACCESS);

CloseHandle(hObjProcessS);

CloseHandle(hProcessT);注意:

一般DuplicateHandle函数没有在三个进程中使用,因为很难知道原进程的句柄值。

要使用IPC机制通知目标进程,新句柄已经拷贝过去。

posted @ 2011-03-03 08:35 xi52qian 阅读(197) | 评论 (1) | 编辑 收藏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go hive skynet_云风的skynet在国内外来看究竟算什么水平?可以一统国内游戏服务端框架吗?...

它和云风过往放出来的东西一样&#xff0c;是非常具有实践性的&#xff0c;可以解决实际开发问题的。目前我所在的手游项目使用 Erlang 进行服务器端开发的&#xff0c;如果重新开始&#xff0c;我会选择使用 skynet。游戏服务器开发中的难点&#xff0c;上面 无瞳已经提到了两…

数据库 测试数据生成_测试数据生成器和对象母亲:另一种外观

数据库 测试数据生成在测试中构造对象通常是一项艰巨的工作&#xff0c;通常会产生大量可重复且难以阅读的代码。 有两种用于处理复杂测试数据的常见解决方案&#xff1a; Object Mother和Test Data Builder 。 两者都有优点和缺点&#xff0c;但是&#xff08;巧妙地&#xff…

电脑机器人_视频|电话积分换平板电脑和扫地机器人?女子拿回家后……-

报警人小王(左二)讲述事情经过。沙坪坝警方供图 华龙网-新重庆客户端 发华龙网-新重庆客户端11月9日11时讯(记者 张勇)“警察叔叔&#xff0c;这个店好坑人哦&#xff0c;我好气愤&#xff01;”11月6日11时许&#xff0c;重庆市沙坪坝区一名年轻女子拨打110报警电话称&#xf…

位置环PID模糊C语言,PID和位置环

EDA365欢迎您登录&#xff01;您需要 登录 才可以下载或查看&#xff0c;没有帐号&#xff1f;注册x所谓PID 自动控制&#xff0c;是对一个确定系统的- -个过程量的自动调节过程:* q* }3 B" * V P# H1)举例说&#xff0c;直流电机的速度&#xff0c;就是-一个过程量&#…

seata xid是什么_阿里开源的分布式事务框架 Seata

1. Seata 概述Seata 是 Simple Extensible Autonomous Transaction Architecture 的简写&#xff0c;由 feascar 改名而来。Seata 是阿里开源的分布式事务框架&#xff0c;属于二阶段提交模式。目前github上已经有 12267 颗星了&#xff0c;也很活跃&#xff0c;最新的提交时间…

python输入print跳到documentation-习题 48: 更复杂的用户输入

习题 48: 更复杂的用户输入 你的游戏可能一路跑得很爽&#xff0c;不过你处理用户输入的方式肯定让你不胜其烦了。每一个房间都需要一套自己的语句&#xff0c;而且只有用户完全输入正确后才能执行。你需要一个设备&#xff0c;它可以允许用户以各种方式输入语汇。例如下面的机…

有关有效企业测试的视频课程

我已经制作了一些有关有效企业测试的视频。 我仍然在现实世界项目中看到这个主题的巨大重要性。 这是我在测试Enterprise Java项目中的经验以及一些示例。 1.介绍和有效的Maven使用 在此视频中&#xff0c;我将介绍测试过程&#xff0c;并演示如何使用Maven在标准企业项目中构…

android自定义弹出对话框,使用FlyDialog实现自定义Android弹窗对话框

前言学习的时候要用到弹窗&#xff0c;但是又觉得i同自带的弹窗样式有点不太美观&#xff0c;搜索资料后发现了FlycoDialog这个开源库,效果很好&#xff0c;而且实现起来也比较方便。先列举一些比较好看的效果:NormalListDialogActionSheetDialog这篇文章主要来讲一下他的自定义…

nacos 本地测试_Nacos集群配置实例(windows下测试)

1、首先 fork 一份 nacos 的代码到自己的 github 库&#xff0c;然后把代码 clone 到本地。git地址&#xff1a;https://github.com/alibaba/nacos.git2、然后将你的项目导入到ideal编辑器中(找到子项目distribution)3、添加集群节点&#xff1a;找到文件distribution->conf…

Android手机如何修改Mac地址,安卓手机怎么修改mac地址

有些时候我们如果绑定了某个mac&#xff0c;那么其他用mac就无法上网&#xff0c;应该怎么修改呢?学习啦小编从网上搜集整理了3种修改安卓手机mac 地址的方法。修改安卓手机mac 地址的方法修改安卓手机mac 地址的方法第一种&#xff1a;软件法下面介绍一款软件 叫物理地址修改…

应用回归分析何晓群_二战上岸人大20年应用统计高分经验帖

首先介绍一下本人的基本情况。男&#xff0c;本科金融学&#xff0c;同时修过数学双学位。一战人大经济学硕&#xff0c;总分 370&#xff08;专业课没过线&#xff09;。二战决定考人大应统专硕&#xff08;除了专业课换了&#xff0c;公共课都一样&#xff09;。二战总分430&…

基于单片机步进电机ppt答辩_基于单片机的步进电机式汽车仪表的设计(含电路原理图,程序)...

基于单片机的步进电机式汽车仪表的设计(含电路原理图,程序)(课题申报表,任务书,开题报告,中期检查表,外文翻译,论文21000字,程序,答辩PPT)摘 要汽车仪表是驾驶者和汽车的交互界面&#xff0c;为驾驶员提供所需要的运行参数、故障、里程等实时信息&#xff0c;是不可或缺的部分。…

android webview js 交互框架,自定义android混合框架开发实践1:实现基础andorid和webview交互...

1. 本地web资源1.构建assets/web文件夹2.创建index.html你的html代码3.使用本地web资源WebView mv findViewById(...);mv.loadUrl("file:///android_asset/web/index.html")2.实现基础的android和js交互(1). 实现js调用andorid方法在Acitivity内构建一个functionJav…

jxls使用excel公司_使用jXLS将Excel文件解析为JavaBeans

jxls使用excel公司这篇文章展示了如何使用jXLS将Excel文件解析为JavaBeans列表。 这是我编写的通用实用程序方法&#xff1a; /** * Parses an excel file into a list of beans. * * param <T> the type of the bean * param xlsFile the excel data file to parse * …

网站部署后无法访问sqlserver_.NET Core跨平台部署

1. Windows-IIS大家对于在IIS上部署.NET站点已经驾轻就熟了&#xff0c;部署.NET Core也没有什么本质区别&#xff0c;但是这其中仍然有一些细节是不同的&#xff0c;下面记录了一些我在部署时遇到的问题1.1 安装.NET Core Windows Server Hosting要在IIS上运行http://ASP.NET …

ajax如何传超长字符串_解决ajax超长字符串、中文乱码问题

在最近的项目测试中发现通过ajax发送超长参数时遇到这个脚本错误&#xff1a;系统找不到指定资源the system cannot locate the resource specified意思是参数太长&#xff0c;无法发送&#xff0c;测试的浏览器是IE6//IE7//IE8&#xff0c;由于利用了ActiveX所以其他浏览器的情…

Android代码数字证书,有关Android中读取证书

最近在项目中遇到了读取证书中内容与读取keystore中对应公钥的需求&#xff0c;在此做一下笔记读取证书最近项目中遇到后台返回个byte[]数组类型的证书&#xff0c;需要从证书中获取相关内容&#xff0c;先看一下相关代码BufferedInputStream mStream null;try {String s new…

Spring Boot中的高级配置文件管理

我们都知道Spring Boot中的配置文件管理及其为不同环境配置应用程序时提供的灵活性。 此功能的另一个强大方面是&#xff0c;在任何给定时间&#xff0c;我们都可以拥有多个活动配置文件。 这样做的好处是我们可以将部署环境配置文件与业务用例相关的配置文件混合在一起。 让我…

先装vs还是先装sql_【家装话题】装修师先装门还是先装地板?

装修先装门还是先装地板从成品保护角度说&#xff0c;先装门&#xff0c;成品保护相对容易&#xff0c;不管是发泡胶的滴落&#xff0c;玻璃胶的污染&#xff0c;安装门用的电动工具&#xff0c;包装垃圾&#xff0c;锯末&#xff0c;钻孔钉凿的冲击。直接在水泥地面上操作&…

python openpyxl模块追加数据_python openpyxl模块实现excel的读取,新表创建及原数据表追加新数据...

当实际工作需要把excel表的数据读取出来&#xff0c;或者把一些统计数据写入excel表中时&#xff0c;一个设计丰富&#xff0c;文档便于寻找的模块就会显得特别的有吸引力&#xff0c;本文对openpyxl模块的一些常见用法做一些记录&#xff0c;方便工作中查询(好记性不如烂笔头)…