Windows NtQueryInformationProcess()
{
https://www.orcode.com/article/Processes_20126324.html
}
{
- 或代码
- 文章
- 编程通用
- 线程,进程及IPC
与NtQueryInformationProcess获取进程信息
{A}
{S0}简介
本文将展示一种方法来读取一个过程的下列项目,主要是使用{A2}进程ID父ID关联掩码退出代码状态命令行过程过程映像文件的路径终端服务会话ID标志,如果目前正在调试过程地址进程环境块(PEB)
这个信息是一个变量声明为一个结构,smPROCESSINFO返回。这种结构是在NtProcessInfo.h定义:
typedef struct _smPROCESSINFO
{
DWORD dwPID;
DWORD dwParentPID;
DWORD dwSessionID;
DWORD dwPEBBaseAddress;
DWORD dwAffinityMask;
LONG dwBasePriority;
LONG dwExitStatus;
BYTE cBeingDebugged;
TCHAR szImgPath[MAX_UNICODE_PATH];
TCHAR szCmdLine[MAX_UNICODE_PATH];
} smPROCESSINFO;
虽然有Windows API的检索上述值,本文将展示如何获得这些值,而让那些不通过Windows
API的。注:此方法使用核心NTDLL.DLL中,这可能在未来的版本中改变结构和功能。 Microsoft建议使用Windows API的";
safelyquot";从系统获得的信息。
的核心职能,以获取上述信息提供NtProcessInfo.h和NtProcessInfo.cpp。只包含到您的项目H
/ CPP文件中,引用的职能,并编译。如果这些文件包括在您的项目/解决方案列表,不要忘了排除他们从构建。
sm_GetNtProcessInfo(),主要功能,需要一个过程ID和一个变量声明为smPROCESSINFO。我建议调用的顺序如下(可以被交换的步骤5和6)的功能:
sm_EnableTokenPrivilege或您自定义令牌的特权功能,使SE_DEBUG_NAME。sm_LoadNTDLLFunctions。保持免费库后的变量返回的HMODULE。获得进程ID。一个手动指定,或使用EnumProcesses,GetCurrentProcessId,CreateToolhelp32Snapshot等。sm_GetNtProcessInfo进程ID和smPROCESSINFO变量。您的smPROCESSINFO变量/数组的内容输出到您所需的介质。从sm_LoadNTDLLFunctions返回的HMODULE变量sm_FreeNTDLLFunctions。
本文的演示应用程序是一个基本的Win32,一个ListView共同控制子窗口,以清单的编制过程内容。也可用于在MFC应用程序没有问题的代码。代码是在Visual Studio。NET 2003 SP1的,是Win2K或以后的打算。启用调试特权
在当前用户读取大多数进程的详细信息,我们必须使调试特权。用户令牌或用户所属的组令牌必须已经调试特权分配。要确定哪些特权令牌,使用{A3}{C}枚举进程ID
为了得到一个正在运行的进程列表,我们将使用{A4}
DWORD EnumProcesses2Array(smPROCESSINFO lpi[MAX_PI]) { DWORD dwPIDs[MAX_PI] = {0}; DWORD dwArraySize = MAX_PI * sizeof(DWORD); DWORD dwSizeNeeded = 0; DWORD dwPIDCount = 0; //== only to have better chance to read processes ===== if(!sm_EnableTokenPrivilege(SE_DEBUG_NAME)) return 0; // Get a list of Process IDs of current running processes if(EnumProcesses((DWORD*)&dwPIDs, dwArraySize, &dwSizeNeeded)) { HMODULE hNtDll = sm_LoadNTDLLFunctions(); if(hNtDll) { // Get detail info on each process dwPIDCount = dwSizeNeeded / sizeof(DWORD); for(DWORD p = 0; p < MAX_PI && p < dwPIDCount; p++) { if(sm_GetNtProcessInfo(dwPIDs[p], &lpi[p])) { // Do something else upon success } } sm_FreeNTDLLFunctions(hNtDll); } } // Return either PID count or MAX_PI whichever is smaller return (DWORD)(dwPIDCount > MAX_PI) ? MAX_PI : dwPIDCount; }
访问NTDLL的功能
NtQueryInformationProcess()函数不导入库,所以我们必须使用{A5}
typedef NTSTATUS (NTAPI *pfnNtQueryInformationProcess)( IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL ); pfnNtQueryInformationProcess gNtQueryInformationProcess; HMODULE sm_LoadNTDLLFunctions() { // Load NTDLL Library and get entry address // for NtQueryInformationProcess HMODULE hNtDll = LoadLibrary(_T("ntdll.dll")); if(hNtDll == NULL) return NULL; gNtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess"); if(gNtQueryInformationProcess == NULL) { FreeLibrary(hNtDll); return NULL; } return hNtDll; }
获取进程的基本信息
我们{A6} PROCESS_QUERY_INFORMATION访问权利得到基本的信息,因为我们将使用ReadProcessMemory()函数来读取在PEB过程,这个过程还必须打开PROCESS_VM_READ访问权。
// Attempt to access process HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID); if(hProcess == INVALID_HANDLE_VALUE) { return FALSE; }
现在,我们为我们的PROCESS_BASIC_INFORMATION结构变量分配内存。
// Try to allocate buffer hHeap = GetProcessHeap(); dwSize = sizeof(smPROCESS_BASIC_INFORMATION); pbi = (smPPROCESS_BASIC_INFORMATION)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize); // Did we successfully allocate memory if(!pbi) { CloseHandle(hProcess); return FALSE; }
这个结构定义在winternl.h和ntddk.h。下面的定义是从WIN2003 {A7}
ntddk.h,因为我winternl.h在Visual Studio
2003和微软MSDN之一不包含尽可能多的细节。我还发现,winternl.h和ntddk.h在编译过程中的相互冲突,所以我决定复制一个新的名字在我的头文件NtProcessInfo.h(包括下载)(作为前缀添加SM)的最新定义。
typedef struct _smPROCESS_BASIC_INFORMATION { LONG ExitStatus; smPPEB PebBaseAddress; ULONG_PTR AffinityMask; LONG BasePriority; ULONG_PTR UniqueProcessId; ULONG_PTR InheritedFromUniqueProcessId; } smPROCESS_BASIC_INFORMATION, *smPPROCESS_BASIC_INFORMATION;
然后,我们通过NtQueryInformationProcess()函数得到一个进程的基本信息。
// Attempt to get basic info on process NTSTATUS dwStatus = gNtQueryInformationProcess(hProcess, ProcessBasicInformation, pbi, dwSize, &dwSizeNeeded); // Did we successfully get basic info on process if(dwStatus >= 0) { // Basic Info spi.dwPID = (DWORD)pbi->UniqueProcessId; spi.dwParentPID = (DWORD)pbi->InheritedFromUniqueProcessId; spi.dwBasePriority = (LONG)pbi->BasePriority; spi.dwExitStatus = (NTSTATUS)pbi->ExitStatus; spi.dwPEBBaseAddress = (DWORD)pbi->PebBaseAddress; spi.dwAffinityMask = (DWORD)pbi->AffinityMask;
读在PEB
从基本的信息,我们已经得到PebBaseAddress指针变量PEB的基地址,如果有的话,。如果地址是不等于零,我们刚刚通过的ReadProcessMemory()函数的地址。如果成功的话,它应该在我们的{A8}结构变量,其中还包含BeingDebugged和SessionID变量返回的信息的过程。
// Read Process Environment Block (PEB) if(pbi->PebBaseAddress) { if(ReadProcessMemory(hProcess, pbi->PebBaseAddress, &peb, sizeof(peb), &dwBytesRead)) { spi.dwSessionID = (DWORD)peb.SessionId; spi.cBeingDebugged = (BYTE)peb.BeingDebugged;
在PEB结构的定义为:
typedef struct _smPEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; smPPEB_LDR_DATA Ldr; smPRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; smPPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId; } smPEB, *smPPEB;
从这一点来说,我们也有内存地址LDR,这是我们本文中未使用。基本上,{A9}
// We got Process Parameters, is CommandLine filled in if(peb_upp.CommandLine.Length > 0) { // Yes, try to read CommandLine pwszBuffer = (WCHAR *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, peb_upp.CommandLine.Length); // If memory was allocated, continue if(pwszBuffer) { if(ReadProcessMemory(hProcess, peb_upp.CommandLine.Buffer, pwszBuffer, peb_upp.CommandLine.Length, &dwBytesRead)) { // if commandline is larger than our variable, truncate if(peb_upp.CommandLine.Length >= sizeof(spi.szCmdLine)) dwBufferSize = sizeof(spi.szCmdLine) - sizeof(TCHAR); else dwBufferSize = peb_upp.CommandLine.Length; // Copy CommandLine to our structure variable #if defined(UNICODE) || (_UNICODE) // Since core NT functions operate in Unicode // there is no conversion if application is // compiled for Unicode StringCbCopyN(spi.szCmdLine, sizeof(spi.szCmdLine), pwszBuffer, dwBufferSize); #else // Since core NT functions operate in Unicode // we must convert to Ansi since our application // is not compiled for Unicode WideCharToMultiByte(CP_ACP, 0, pwszBuffer, (int)(dwBufferSize / sizeof(WCHAR)), spi.szCmdLine, sizeof(spi.szCmdLine), NULL, NULL); #endif } if(!HeapFree(hHeap, 0, pwszBuffer)) { // failed to free memory bReturnStatus = FALSE; goto gnpiFreeMemFailed; } } } // Read CommandLine in Process Parameters
... ... ImagePathName变量{A10}
// We got Process Parameters, is ImagePathName filled in if(peb_upp.ImagePathName.Length > 0) { // Yes, try to read Image Path pwszBuffer = (WCHAR *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, peb_upp.ImagePathName.Length); // If memory was allocated, continue if(pwszBuffer) { if(ReadProcessMemory(hProcess, peb_upp.ImagePathName.Buffer, pwszBuffer, peb_upp.ImagePathName.Length, &dwBytesRead)) { // if image path is larger than our variable, truncate if(peb_upp.ImagePathName.Length >= sizeof(spi.szImgPath)) dwBufferSize = sizeof(spi.szImgPath) - sizeof(TCHAR); else dwBufferSize = peb_upp.ImagePathName.Length; // Copy ImagePathName to our structure variable #if defined(UNICODE) || (_UNICODE) // Since core NT functions operate in Unicode // there is no conversion if application is // compiled for Unicode StringCbCopyN(spi.szImgPath, sizeof(spi.szImgPath), pwszBuffer, dwBufferSize); #else // Since core NT functions operate in Unicode // we must convert to Ansi since our application // is not compiled for Unicode WideCharToMultiByte(CP_ACP, 0, pwszBuffer, (int)(dwBufferSize / sizeof(WCHAR)), spi.szImgPath, sizeof(spi.szImgPath), NULL, NULL); #endif } if(!HeapFree(hHeap, 0, pwszBuffer)) { // failed to free memory bReturnStatus = FALSE; goto gnpiFreeMemFailed; } } } // Read ImagePathName in Process Parameters
(PID
= 4在XP上WIN2K后,8,并在NT 4 2)对于系统的过程中,我们手动指定进程的路径,因为我们知道它是%SystemRoot%\
SYSTEM32 \ NTOSKRNL.EXE但不是由API返回。 NTOSKRNL.EXE也可以被NTKRNLMP.EXE {A11}
// System process for WinXP and later is PID 4 and we cannot access // PEB, but we know it is aka ntoskrnl.exe so we will manually define it if(spi.dwPID == 4) { ExpandEnvironmentStrings(_T("%SystemRoot%\\System32\\ntoskrnl.exe"), spi.szImgPath, sizeof(spi.szImgPath)); }
上述与PROCESS_BASIC_INFORMATION结构,{A12}
typedef struct _smRTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; } smRTL_USER_PROCESS_PARAMETERS, *smPRTL_USER_PROCESS_PARAMETERS;
净化
在这里,我们免费NTDLL.DLL中我们前面加载。这就是它!
void sm_FreeNTDLLFunctions(HMODULE hNtDll) { if(hNtDll) FreeLibrary(hNtDll); gNtQueryInformationProcess = NULL; }
兴趣点
我写这篇文章分享我学到的方法,而试图得到我自己的经验,而无需使用简单的{A13}一个基本的过程中浏览器的进程信息。
一些quot; safequot; Windows
API函数来获得另一个进程的信息是:ProcessIdToSessionIdCheckRemoteDebuggerPresentGetExitCodeProcessGetProcessAffinityMaskGetProcessImageFileNameCreateRemoteThread的其他{A14}
注:我没有在演示应用程序的调试过程中收到以下消息,但出现之前发生,以WinMain的,似乎是因为第二次机会没有抛出异常处理:
"First-chance exception at 0x7c918fea in GetNtProcessInfo.exe: 0xC0000005: Access violation writing location 0x00000010."
我没有得到与现实世界实现NtProcessInfo.h和NtProcessInfo.cpp此异常。历史最初的版本。
回答
谢谢你张贴,GetProcessimagefilename现在已经一个星期的痛苦
但我只是想知道,如果有什么办法可以在Vb.net?
'All the code I could scrape together 'Some of these functions are VB6, I tried converting Strptr,varptr etc.. Imports Microsoft.VisualBasic Imports System.Runtime.InteropServices Public Class getimagefilename Private Const ProcessImageFileName = 27 Private Const STATUS_INFO_LENGTH_MISMATCH = &HC0000004 Private Const PROCESS_QUERY_INFORMATION = &H400& Private Const PROCESS_VM_READ = &H10& Private Const HEAP_ZERO_MEMORY = &H8& Private Const MAX_PATH = 260 Private Structure UNICODE_STRING Dim Length As Integer Dim MaximumLength As Integer Dim Buffer As Long End Structure Private Declare Function GetProcessHeap Lib "kernel32.dll" () As Long Private Declare Function HeapAlloc Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long Private Declare Function HeapFree Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Long) As Long Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessid As Long) As Long Private Declare Function NtQueryInformationProcess Lib "ntdll.dll" (ByVal ProcessHandle As Long, ByVal ProcessInformationClass As Long, ByVal ProcessInformation As Long, ByVal ProcessInformationLength As Long, ByRef ReturnLength As Long) As Long Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (ByVal lpDest As Long, ByVal lpSource _ As Long, ByVal cbCopy As Long) Public Function VarPtr(ByVal e As Object) As Integer Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned) Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32 GC.Free() Return GC2 End Function Public Function strptr(ByVal source As String, ByVal dest As String) As String Return dest = dest.Insert(0, source) End Function Public Function GetProcessNameByPid(ByVal pid As Long) As String Dim uni As UNICODE_STRING Dim Buffer As Long Dim hProcess As Long Dim FileName As String Dim cbNeeded As Long hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, pid) If hProcess = 0 Then Else ' Get the buffer size needed for the call. If NtQueryInformationProcess(hProcess, ProcessImageFileName, VarPtr(uni), 8, cbNeeded) = STATUS_INFO_LENGTH_MISMATCH Then ' Allocate the required buffer from the heap. Buffer = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, cbNeeded) If NtQueryInformationProcess(hProcess, ProcessImageFileName, Buffer, cbNeeded, cbNeeded) = 0 Then ' UNICODE_STRING RtlMoveMemory(VarPtr(uni), Buffer&, Len(uni)) FileName = Strings.Left(uni.Length / 2, vbNullChar) RtlMoveMemory(strptr(FileName, FileName), uni.Buffer, uni.Length) Return FileName End If HeapFree(GetProcessHeap, 0, Buffer) End If End If CloseHandle(hProcess) End Function End Class
我编译成功
感谢
修改上,3月29日(星期一),2010 0:25
。通缉致以谢意缺少魔法酱,制作精良的代码
我有一个过程的阅读器应用程序(,因为每个人),但我是越来越少的进程在任务管理器,然后在"Iarsn TaskInfo"计划上市。一个非常关键的一块,使DEGUG privaledges令牌。
你是唯一的编程细节这非常关键的一点,我所看到的许多代码和程序样本。
谢谢你们,让您的旅途好运!
荃湾
BOOL sm_EnableTokenPrivilege(LPCTSTR pszPrivilege)
{处理hToken = 0;TOKEN_PRIVILEGES TKP = {0}
/ /获取了这一进程的令牌。
如果(OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY,放大器; hToken))
{
返回FALSE;
}
/ /获取特权的LUID。
(LookupPrivilegeValue(NULL,pszPrivilege,
安培。tkp.Privileges [0] LUID))
{
&
#160; tkp.PrivilegeCount = 1; / /一个权限设置
tkp.Privileges [0]属性= SE_PRIVILEGE_ENABLED;
/ /设置为这一进程的特权。
AdjustTokenPrivileges(hToken,FALSE,则放大器; TKP,0,
(PTOKEN_PRIVILEGES)NULL,0);
如果(GetLastError函数()!= ERROR_SUCCESS)
返回FALSE;
返回TRUE;}
返回FALSE;
}
这种方法是发生句柄泄漏...
所以..下面的
BOOL sm_EnableTokenPrivilege(LPCTSTR pszPrivilege)
{处理hToken = 0;TOKEN_PRIVILEGES TKP = {0}
BOOL bResult = FALSE;
/ /获取这个过程中的信物。
如果(OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY,放大器; hToken))
{
&#
160;返回FALSE;
}
/ /获取特权的LUID。
(LookupPrivilegeValue(NULL,pszPrivilege,
安培。tkp.Privileges [0] LUID))
{
tkp.PrivilegeCount = 1; / /一个权限设置
tkp.Privileges [0]属性= SE_PRIVILEGE_ENABLED;
/ /设置为这一进程的特权。
AdjustTokenPrivileges(hToken,FALSE,则放大器; TKP,0,
(PTOKEN_PRIVILEGES)NULL,0);
如果(GetLastError函数()== ERROR_SUCCESS)
bResult = TRUE;
}
CloseHandle(hToken);返回bResult;
}
THX ...
11
您好,
我下载的,这与VC 6工程的最后一个平台SDK(二月
2003年):http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
然而IM得到一个奇怪的错误,当我编译。我做的是
以下内容:
- 从开始菜单运行这个快捷方式来设置变量:设置Windows
XP的32位编译环境(零售)。LNK
- 打开VC 6,创建一个新的Win32简单的应用程序
- 包括winternl.h
这是代码:
#包括"stdafx.h中"
#
INT APIENTRY的WinMain(HINSTANCE HINSTANCE,HINSTANCE hPrevInstance,
INT LPSTR lpCmdLine,nCmdShow){
0;PROCESS_BASIC_INFORMATION P;
返回0;
}
编译时,我得到这些错误:
错误C2065:'PROCESS_BASIC_INFORMATION":未声明的标识符
错误C2146:语法错误:缺少";"前标识符'P'
错误C2065:"P":未声明的标识符
包括是正确的,但仍认为(任何)成员从
头不被认可。
如果我使用其他头(只试过一对夫妇)一切正常。
任何想法?
它是一个无论是暂停或无NTDLL,suspendthread / ResumeThread线程的状态可以查询?
在2006年1月MSDN库,它说:"NtQueryInformationProcess是在Windows 2000和Windows XP中使用,它可能会改变或在后续版本中不可用的应用程序应该使用列在候补功能。这个话题。"
但在目前的DVD的MSDN库,这是使先进的我可以不甚至管理的"帮助"菜单中的版本的邮票的,它只是说"[NtQueryInformationProcess可能被改变或在未来的Windows版本中不可用的应用程序应该使用的第二功能本主题中列出。]",和在线的MSDN说同样的事情。
我没有实际测试,诱惑来推断,他们留在Vista的功能,但谁知道什么政策将在下一个版本中,HMM的呢?
PG - AZ
}
Windows NtQueryInformationProcess()的更多相关文章
- 深入解析Windows操作系统笔记——CH2系统结构
2.系统结构 本章主要介绍系统的总体结构,关键部件之间的交互,以及运行在什么环境. 2.系统结构 2.1 需求和设计目标 2.2 操作系统模型 2.3 总体结构 2.3.1 可移植性 2.3.2 对称 ...
- windows进程/线程创建过程 --- windows操作系统学习
有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...
- Windows系统结构
四种用户模式进程:1.系统支持进程,比如登录进程和会话管理器,并不是Windows服务,不有服务控制管理器启动2.服务进程,一些以Windows服务方式来运行的组件3.用户应用进程4.环境子系统服务器 ...
- delphi R3下 跨进程获取DLL信息 NtQueryInformationProcess
unit APIUnit; { GetProcessModuleHandle API Unit Ring3调用NtQueryInformationProcess实现跨进程获取DLL句柄 } inter ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- [源码]一键获取windows系统登陆密码vc6版源码
[源码]一键获取windows系统登陆密码vc6版源码支持:XP/2000/2003/WIN7/2008等 此版本编译出来的程序体积较小几十KB... 而vs版则1点几M,体积整整大了2-30倍对某些 ...
- [5]windows内核情景分析---进程线程
本篇主要讲述进程的启动过程.线程的调度与切换.进程挂靠 进程的启动过程: BOOL CreateProcess ( LPCTSTR lpApplicationName, ...
- Windows 8的用户模式Shim Engine小探及利用
转载: https://bbs.pediy.com/thread-175483.htm Windows Shim Engine,即Windows 兼容性模式实现引擎,在exe文件的属性对话框中有一个兼 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
随机推荐
- 字符串操作——C语言实现
代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <asse ...
- SQL Wildcards 通配符
SQL Wildcards通配符 通配符用于替换字符串中的任何其他字符. 通配符与SQL LIKE运算符一起使用.在WHERE子句中使用LIKE运算符来搜索列中的指定模式. 有两个通配符与LIKE运算 ...
- python--有参装饰器、迭代器
有参装饰器的引入: import time import random from functools import wraps def timmer(func): @wraps(func) def w ...
- UVa 11806 Cheerleaders (容斥原理+二进制表示状态)
In most professional sporting events, cheerleaders play a major role in entertaining the spectators. ...
- PHP浮点计算结果返回异常问题
php中如果直接小数点进行计算的话.比如16.8*3var_dump是50.4.但是return就变成了50.400000000000006.至于是什么原因本人尚不得而知.解决方法是用把计算放入下面的 ...
- JQ-jQuery-Ajax:jQuery Ajax 操作函数
ylbtech-JQ-jQuery-Ajax:jQuery Ajax 操作函数 1.返回顶部 1. jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允 ...
- 1、jQuery操作Dom
1.添加元素 <code> <script language="JavaScript">$().ready(function(){$("input ...
- HTML5网页如何让所有的浏览器都能识别语义元素标签样式
浏览器对语义元素的支持情况 如今HTML5愈来愈引发大家的关注了,但目前支持HTML5的浏览器还不是主流,特别是国内用户近50%以上仍旧使用IE6,由于支持HTML5的IE9不支持Xp系统安装,这样未 ...
- 转 MySQL数据库面试问题集锦
如何设计一个高并发的系统 ① 数据库的优化,包括合理的事务隔离级别.SQL语句优化.索引的优化 ② 使用缓存,尽量减少数据库 IO ③ 分布式数据库.分布式缓存 ④ 服务器的负载均衡 锁的优化策略 ① ...
- python 根据字典的键值进行排序
1.利用key排序 d = {'d1':2, 'd2':4, 'd4':1,'d3':3,} for k in sorted(d): print(k,d[k]) d1 2d2 4d3 3d4 1 2. ...