推荐
最新
cron, at
crontab -e: 无需用户列,普通用户/var/log/cron: 运行日志/etc/crontab: 只有root允许编辑(多了一个用户列);
编辑后不需要重启!/var/spool/cron/username: 其他用户
# 如分钟填2,表示一小时的第2分钟;
# 单独的'*'表示每一个最小的精度如:每分钟、每周几... 如果是每分钟都填星号
# 分钟 小时 天 月 星期 USER 命令/脚本
# 0 18 * 1-3 2,5 root NULL :1-3月份,每个星期2,5的下午6点
# */2 0-2 * 9-12 1-5 root sh :9-12月份,周1-周5,0:00到2:00点,每隔两分钟,执行脚本sh
# 2W: 这个月2号的最近工作日,若2号是周六则实际为4号.不能跨月! LW:表示这个月最后一周的工作日!
# L: 一个月的最后一天
# 6L: 一个月的最后一个星期五;不加表示周六:7!
# 7#3: 本月第3周的周六
at
指定在某个时间点做某事
vs精简安装
目的
- vs安装冗余度过大,深度占用系统磁盘空间
- 用最小体积安装vs
步骤
- 修该 Setup\vs_setup.pdi(locdata.ini为说明文件) 中 [Complete Dependency List]/[Microsoft Visual Studio 2010…] 为:
gencomp15
gencomp784
gencomp16
gencomp387,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
gencomp384,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
gencomp43,{5883FD8F-CE63-48BC-8A02-D1633E41F6C3}
gencomp64,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
gencomp48,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
vs_setup.dll
gencomp478,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
gencomp108,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
gencomp49,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}
- 修改 Setup\baseline.dat,将 [vs_setup.dll] 中 UseMediaFwlinks=1 后全部删除.(Framwork)
- 不要删除以下配置项:
- Microsoft Visual Studio Macro Tools
- Microsoft .NET Framework 4 Extended
//NET Framework 4扩展. 不能删除. - Microsoft Visual C++ 开发组件包
Microsoft Visual C++ 2008 Redistributable
Microsoft Visual C++ 2008 Redistributable
Microsoft Visual C++ 2010 x64 Runtime
Microsoft Visual C++ 2010 x86 Runtime
Microsoft SQL Server Compact 3.5 SP2 CHS
//删除会影响IntelliSence, WCU\SSCE\SSCERuntime_x86-enu.msiMicrosoft SQL Server 2008 R2 Data-Tier Application Project//WCU\DAC\DACProjectSystemSetup_enu.msiCrystalReports //WCU\Crystal Reports\CrystalReportsTemplates.msi-->右键-卸载. - Microsoft .NET Framework 4 Client Profile
//优化.net客户端的运行. "可以删除,但不建议删除".Microsoft .NET Framework 4 Multi-Targeting Pack//NET跨平台准备的东西. "可以删除,不建议删除".
Registry
Header file
/**
* @file xRegistry.h
* @date 2012 5.18/周六 14:20:32
* @author lei email:[email protected]
* @copyright GNU Public License.
* @remark 注册表编辑
*/
#ifndef AFX_XREGISTRY_H__98332335_740E_4E47_8F08_0689B508E55B__INCLUDED_
#define AFX_XREGISTRY_H__98332335_740E_4E47_8F08_0689B508E55B__INCLUDED_
#include <tchar.h>
#include <vector>
#ifdef __AFXWIN_H__
#include <afxtempl.h> //方便使用CStringArray
#endif
class Registry
{
typedef struct _RegItem {
TCHAR szItemName[256];
unsigned char* pValueBuf;
unsigned long dwValBufLen;
} RegItem;
public:
// defroot: HKEY_CURRENT_USER(0x80000001)
Registry(const TCHAR* lpDefKeyName=_T("Software\\leizi"), void* hDefRootKey=(void*)0x80000001);
virtual ~Registry();
bool SetRootKey(void* hRootKey=(void*)0x80000001);
bool OpenKey(const TCHAR* lpRegKey,bool bCreateIfNoExist=false);
void GetKey(TCHAR* lpszRegKey/*OUT*/, void* *phRootKey/*OUT*/);
bool SetValue(const TCHAR* lpItem,void *pValue,unsigned long dwLen=sizeof(unsigned long),unsigned long dwType=4); //REG_DWORD
bool GetValue(const TCHAR* lpItem,void *pValue,unsigned long *pdwLen=NULL,unsigned long *pdwType=NULL) ;
bool DelValue(const TCHAR* lpItem) ;
// exepath为空时表当前程序的全路径
void SetAutoRunOnBoot(TCHAR* pStartName,bool bRunFlag,TCHAR* pExeFullPath=NULL);
// RegItems由使用者释放(free)
bool EnumKeyValues(std::vector<RegItem*>& arrValues,const TCHAR* lpRegKey=NULL);
#ifdef UNICODE
bool EnumSubkeys(std::vector<std::wstring>& arrSubkeys,const TCHAR* lpRegKey=NULL);
#else
bool EnumSubkeys(std::vector<std::string>& arrSubkeys,const TCHAR* lpRegKey=NULL);
#endif
#ifdef __AFXWIN_H__
bool EnumKeyValues(CArray<RegItem*,RegItem*> &arrValues,const TCHAR* lpRegKey=NULL);
bool EnumSubkeys(CStringArray &arrSubkeys,const TCHAR* lpRegKey=NULL);
#endif
void FreeRegItem(void *pItem);
//////////////////////////////////////////////////////////////////////////
private:
void* m_hKeyOpened ;
void* m_hRootKey ;
TCHAR m_szOpenedKey[1024];
};
#endif
source file
#include "stdafx.h"
#include "xRegistry.h"
#include <string>
#include <windows.h>
#include <winreg.h> //using windows.h
#pragma warning (disable: 4996)
Registry::Registry(const TCHAR* lpDefKeyName/*Software/leizi*/, void* hDefRootKey/*HKEY_CURRENT_USER*/)
{
m_hKeyOpened = NULL;
SetRootKey(hDefRootKey);
OpenKey(lpDefKeyName,true);
}
Registry::~Registry()
{
if (m_hKeyOpened != NULL) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
}
}
bool Registry::SetRootKey(void* hRootKey/*HKEY_CURRENT_USER*/)
{
if (hRootKey != HKEY_CLASSES_ROOT &&
hRootKey != HKEY_CURRENT_USER &&
hRootKey != HKEY_LOCAL_MACHINE &&
hRootKey != HKEY_USERS)
return false;
m_hRootKey = hRootKey;
return true;
}
int trimleft(TCHAR* s)
{
if (!s) return -1;
TCHAR* p = s;
while (*p && ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p))) p++;
if (*p) _tcscpy(s, p);
else *s = 0;
return 0;
}
int trimright(TCHAR* s)
{
if (!s) return -1;
TCHAR* p = s + _tcslen(s) - 1;
while (*p && (p - s) && ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p))) p --;
*(p + 1) = 0;
if ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p)) *p = 0;
return 0;
}
// if the subkey already exist,this function just like RegOpenKeyEx().
// if the subkey does not exist,we will call RegCreateKey() recursively
bool Registry::OpenKey(const TCHAR* lpRegKey,bool bCreateIfNoExist/*=TRUE*/)
{
if (!lpRegKey) return false;
if (m_hKeyOpened != NULL) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
}
// here,save the opened key handle
if (ERROR_SUCCESS == RegOpenKeyEx((HKEY)m_hRootKey,lpRegKey,0,KEY_ALL_ACCESS, (HKEY*)&m_hKeyOpened)) {
_tcscpy(m_szOpenedKey,lpRegKey);
return true;
} else { // this subkey does'nt exist in registry
if (bCreateIfNoExist) {
TCHAR szPath[MAX_PATH];
_tcscpy(szPath,lpRegKey);
trimright(szPath);
#ifdef UNICODE
std::wstring sReg(szPath);
sReg.append(_T("\\"));
std::wstring sTmp;
#else
std::string sReg(szPath);
sReg.append(_T("\\"));
std::string sTmp;
#endif
int nFind = 0;
while (1) {
nFind = sReg.find(_T('\\'),nFind);
if (nFind < 0) break;
if (m_hKeyOpened) RegCloseKey((HKEY)m_hKeyOpened);
sTmp = sReg.substr(0,nFind);
if (ERROR_SUCCESS == RegOpenKey((HKEY)m_hRootKey,sTmp.c_str(), (HKEY*)&m_hKeyOpened)) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
} else {
RegCreateKey((HKEY)m_hRootKey,sTmp.c_str(),(HKEY*)&m_hKeyOpened);
}
nFind++;
}
}
if (m_hKeyOpened != NULL)
return true;
}
m_hRootKey = HKEY_CURRENT_USER;
m_hKeyOpened = NULL;
return false;
}
void Registry::GetKey(TCHAR* lpszRegKey, void**phRootKey)
{
if (!lpszRegKey || !phRootKey) return;
*phRootKey = m_hRootKey;
_tcscpy(lpszRegKey,m_szOpenedKey);
}
// if the value(wait be setted) is a string,the third param is 0 & last param is ignored
bool Registry::SetValue(const TCHAR* lpItem,void* pValue,unsigned long dwLen/*sizeof(DWORD)*/,unsigned long dwType/*=REG_DWORD*/)
{
unsigned long dwSetType = dwType;
unsigned long dwSetSize = dwLen;
if (dwLen == 0) {
dwSetType = REG_SZ;
dwSetSize = _tcslen((TCHAR*)pValue);
}
if (m_hKeyOpened==NULL || pValue==NULL ||
ERROR_SUCCESS!=RegSetValueEx((HKEY)m_hKeyOpened,lpItem,0,dwSetType,(CONST BYTE *)pValue,dwSetSize))
return false;
return true;
}
bool Registry::GetValue(const TCHAR* lpItem,void *pValue,unsigned long *pdwLen/*=NULL*/,unsigned long *pdwType/*NULL*/)
{
if (m_hKeyOpened==NULL || pValue==NULL)
return false;
unsigned long dwLen=0,dwType=0;
// first check the item to see if it exist. if it does exist,get the value, type and length
bool bGetOK = (ERROR_SUCCESS == RegQueryValueEx((HKEY)m_hKeyOpened,lpItem,NULL,&dwType,NULL,&dwLen) &&
ERROR_SUCCESS == RegQueryValueEx((HKEY)m_hKeyOpened,lpItem,NULL,&dwType,(BYTE*)pValue,&dwLen));
if (pdwType != NULL)
*pdwType = dwType;
if (pdwLen != NULL)
*pdwLen = dwLen;
if (dwType == REG_SZ)
((TCHAR *)pValue)[dwLen] = 0;
return bGetOK;
}
void Registry::FreeRegItem(void *pItem)
{
if (pItem != NULL) {
if (((RegItem*)pItem)->pValueBuf != NULL)
free(((RegItem*)pItem)->pValueBuf);
free(pItem);
pItem = NULL;
}
}
bool Registry::DelValue(const TCHAR* lpItem)
{
if (m_hKeyOpened==NULL || ERROR_SUCCESS!=RegDeleteValue((HKEY)m_hKeyOpened,lpItem))
return false;
return true;
}
#ifdef __AFXWIN_H__
// you are be responsable for freeing the mem which is associate with the first arg
bool Registry::EnumKeyValues(CArray<RegItem*,RegItem*> &arrValues,const TCHAR* lpRegKey/*NULL*/)
{
if (!lpRegKey)
return false;
// 先保存之前打开的键
TCHAR szOldKeyName[1024] = {0};
_tcscpy(szOldKeyName,m_szOpenedKey);
arrValues.RemoveAll();
// 会改变 m_sOpenedKey
if (!OpenKey(lpRegKey,false))
return false;
TCHAR szItemName[256] ={0};
BYTE szItemValue[4096] ={0};
for (unsigned long i=0; ; i++)
{
unsigned long dwType = 0;
unsigned long dwNameLen = sizeof(szItemName);
unsigned long dwValueLen = sizeof(szItemValue);
memset(szItemName ,0,sizeof(szItemName));
memset(szItemValue,0,sizeof(szItemValue));
if (ERROR_NO_MORE_ITEMS == RegEnumValue((HKEY)m_hKeyOpened,i,szItemName,&dwNameLen,0,&dwType,szItemValue,&dwValueLen))
break;
RegItem* lpItem = (RegItem*)calloc(1,sizeof(RegItem));
_tcscpy(lpItem->szItemName,szItemName);
lpItem->pValueBuf = (BYTE *)calloc(dwValueLen+1,sizeof(BYTE));
memcpy(lpItem->pValueBuf,szItemValue,dwValueLen);
arrValues.Add(lpItem);
}
OpenKey(szOldKeyName,false); // 恢复之间打开的key
return true;
}
#endif
bool Registry::EnumKeyValues( std::vector<RegItem*>& arrValues,const TCHAR* lpRegKey/*=NULL*/)
{
if (!lpRegKey) return false;
TCHAR szOldKeyName[1024] = {0};
_tcscpy(szOldKeyName,m_szOpenedKey);
arrValues.clear();
if (!OpenKey(lpRegKey,false))
return false;
TCHAR szItemName[256] ={0};
BYTE szItemValue[4096] ={0};
for (unsigned long i=0; ; i++)
{
unsigned long dwType = 0;
unsigned long dwNameLen = sizeof(szItemName);
unsigned long dwValueLen = sizeof(szItemValue);
memset(szItemName ,0,sizeof(szItemName));
memset(szItemValue,0,sizeof(szItemValue));
if (ERROR_NO_MORE_ITEMS == RegEnumValue((HKEY)m_hKeyOpened,i,szItemName,&dwNameLen,0,&dwType,szItemValue,&dwValueLen))
break;
RegItem* lpItem = (RegItem*)calloc(1,sizeof(RegItem));
_tcscpy(lpItem->szItemName,szItemName);
lpItem->pValueBuf = (BYTE *)calloc(dwValueLen+1,sizeof(BYTE));
memcpy(lpItem->pValueBuf,szItemValue,dwValueLen);
arrValues.push_back(lpItem);
}
OpenKey(szOldKeyName,false); // rollback
return true;
}
#ifdef __AFXWIN_H__
bool Registry::EnumSubkeys(CStringArray &arrSubkeys,const TCHAR* lpRegKey/*NULL*/)
{
if (!lpRegKey) return false;
if (!OpenKey(lpRegKey,false)) return false;
TCHAR szKeyName[1024] = {0};
arrSubkeys.RemoveAll();
for (unsigned long i=0; ; i++) {
if (ERROR_NO_MORE_ITEMS == RegEnumKey((HKEY)m_hKeyOpened,i,szKeyName,1024))
break;
arrSubkeys.Add(szKeyName);
}
OpenKey(m_szOpenedKey,false);
return true;
}
#endif
#ifdef UNICODE
bool Registry::EnumSubkeys(std::vector<std::wstring>& arrSubkeys,const TCHAR* lpRegKey/*=NULL*/)
#else
bool Registry::EnumSubkeys(std::vector<std::string>& arrSubkeys,const TCHAR* lpRegKey/*=NULL*/)
#endif
{
if (!lpRegKey) return false;
// 打开注册表
if (!OpenKey(lpRegKey,false)) return false;
TCHAR szKeyName[1024] = {0};
arrSubkeys.clear();
for (unsigned long i=0; ; i++) {
if (ERROR_NO_MORE_ITEMS == RegEnumKey((HKEY)m_hKeyOpened,i,szKeyName,1024))
break;
arrSubkeys.push_back(szKeyName);
}
OpenKey(m_szOpenedKey,false);
return true;
}
void Registry::SetAutoRunOnBoot(TCHAR *pStartName,bool bEnable,TCHAR *pExeFullPath/*=NULL*/)
{
HKEY hKey;
RegOpenKey(HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), &hKey);
if (!bEnable) {
RegDeleteValue(hKey, pStartName);
RegCloseKey(hKey);
return;
}
#ifdef UNICODE
std::wstring sRunPath(pExeFullPath);
#else
std::string sRunPath(pExeFullPath);
#endif
TCHAR szAppPathName[MAX_PATH];
GetModuleFileName(NULL,szAppPathName,MAX_PATH);
if (sRunPath.empty()) sRunPath = szAppPathName;
sRunPath.append(_T(" /OnSysStart"));
const BYTE *pData = (BYTE *)sRunPath.c_str();
RegSetValueEx(hKey, pStartName, 0, REG_SZ, pData, sRunPath.length());
RegCloseKey(hKey);
}
Batch
http://www.bathome.net/
隐藏CMD运行窗口
特殊符号
| symbol | function |
|---|---|
. | 在一般命令中当作空格, 在echo命令中当作空行 |
^ | 字符画某个符号,如: echo ^> |
& | 组合命令,前后没有因果关系;只是为了写在一行; 注意:左侧不要有空格(会被左侧理解成1个字符),右侧空格无所谓! |
&& | 短路特性.前一个执行成功,才执行后面 |
|| | 前一个执行失败,才执行后面的命令; |表管道 |
1>nul | 将语句产生的输出信息屏蔽(或>nul); |
2>nul | 将语句产生的错误信息屏蔽 |
基本变量
cmd自上而下、逐条处理批处理语句,注意:以下算作1条语句: for if else & || && | ()
这很类似于宏展开,需要延后这种行为?: setlocal EnableDelayedExpansion
MFC
程序启动流程
- 系统
shell加载程序的code、data、dll并调用CreateProcess()创建了一个代表你程序的进程 - 启动第一个线程(
PCB,TCB等的创建)
MFC程序启动流程
_tWinMain–>AfxWinMain(WINMAIN.CPP 21)AfxWinMain()负责调用CWinApp中的InitApplication(),InitInstance(),Run()等几个主要函数.
WinMain
int WINAPI WinMain(HINSTANCE hInstance/*当前进程句柄*/, HINSTANCE hPrevInstance/*win32:NULL*/, LPSTR cmd/*argv*/, int show/*maxmize...*/) {
WNDCLASS wc = {0};
wc.lpszClassName = "ZClass";
wc.lpfnWndProc = (WNDPROC)ZWindowProc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.style = CS_VERDRAW | CS_HREDRAW | CS_NOCLOSE/*禁止标题栏关闭*/;
if (!RegisterClass(&wc)) { return 0; }
// CreateWindow会产生WM_CREATE消息,这是窗口过程收到的第1个消息.
HWND hWndMain = CreateWindow("ZClass", "caption", WS_OVERLAPPEDWINDOW, 0,0,8,8, NULL,NULL, hInstance, NULL);
ShowWindow(hWndMain, SW_SHOW);
// emit WM_PAINT, 这是窗口过程的第2个消息!
UpdateWindow(hWndMain);
/* 消息循环 */
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) { // NULL:获取所有窗口消息;2个0:不过滤
// 将WM_KEYDOWN翻译成WM_CHAR.
TranslateMessage(&msg);
// 将消息转发(OS)到窗口过程!
DispatchMessage(&msg);
}
return 0;
}
Message Map
CObject实现了运行时类型识别功能:CObject::IsKindOf()CCmdTarget实现了消息映射CWinThread没有保存消息映射表,故不适用其父类:BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget)declare_message_map这些宏主要是为了使当前消息映射节点加入到消息映射的链表中去.AFX_MSGMAP的类都保存了一张表,记录了"消息-处理函数"之间的对应关系
消息的种类
- 命令消息:
WM_COMAMDN,CCmdTarget; UI对象、菜单、工具栏、按钮 - 控件消息:
WM_NOTIFY,也属于命令消息的一种,是控件发送给父窗口的"通知消息"; - 标准消息:
WM_PAINT,WM_CREATE,WM_CHAR,WM_LBUTTONDOWN..除了上面两种之外的消息.CWnd不需要我们指定函数名!
AFX_MSGMAP
enum AfxSig { // 消息映射响应函数参数及返回值的类型
AfxSig_end = 0, // [marks end of message map]
AfxSig_bD, // BOOL (CDC*)
AfxSig_bb, // BOOL (BOOL)...
};
typedef void (CCmdTarget::*AFX_PMSG)(void); // CCmdTarget类的void-void成员函数指针类型
struct AFX_MSGMAP_ENTRY { // 记录(控件上的)消息所对应的"消息处理函数"----消息映射的节点
UINT nMessage; // WM_CREATE、WM_COMMAND、WM_MOVE、WM_SIZE、WM_PAINT...
UINT nCode; // 控件消息的控制码,如: BN_CLICKED、
UINT nID; // 控件ID:IDC_BUTTON1.., 0:标准消息
UINT nLastID; // 指定一定范围内的消息被映射,或两者一样
UINT nSig; // pfn函数类型.见上方AfxSig的定义
AFX_PMSG pfn; // 是一个指向CCmdTarget类非静态成员函数指针
};
struct AFX_MSGMAP { // 消息映射链表,便于从年轻的消息映射节点走访到最老的消息映射节点.
const AFX_MSGMAP* pBaseMap; // 记录基类的(baseClass)messageMap成员以便向上走访,基类消息映射表使子类可以走访到基类,类似于虚函数
const AFX_MSGMAP_ENTRY* lpEntries; // _messageEntries[]成员的地址
};
DECLARE_MESSAGE_MAP
下面都定义了_AFXDLL版本(动态连接到MFC-dll)

















