这两天想做一下windows系统下图标的修改,让程序有更新的时候能够更新图标的外观,达到提醒的作用,360,QQ经常采用这种方式进行更新的提示,也有采用弹框的方式来提示,用新版QVOD的同事可能见到过类似的。废话不说,我的思路是:

(1)检测程序更新

(2)检测windows桌面图标中是够含有需要的,如果没有则需要创建,如果有则准备更新图标

(3)根据跟新的内容,程序自己创建新的图像,修改快捷方式的图标

这种方法需要开机之后,存在一个系统进程来检测这种更新,360就是这样干的~~还有一个弊端是程序需要检测桌面快捷方式的信息来判断是不是自己想去修改的,OK ,这个问题其实可以通过LNK文件的属性,应用信息,名字等问题来解决。 下面是实现过程

1 ICON文件的操作

ICON文件的格式和BMP文件的格式的类似,不过增加了层数的东西,一个ICON文件中可能有几份数据,不同的分辨率,ICON文件的格式主要定义如下:

//ICON文件存储格式
typedef struct
{
byte bwidth; // width, in pixels, of the image
byte bheight; // height, in pixels, of the image
byte bcolorcount; // number of colors in image (0 if >=8bpp)
byte breserved; // reserved ( must be 0)
WORD wplanes; // color planes
WORD wbitcount; // bits per pixel
DWORD dwbytesinres; // how many bytes in this resource?
DWORD dwimageoffset; // where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY; //ICON文件目录
typedef struct
{
WORD idReserved; // Reserved
WORD idType; // resource type (1 for icons)
WORD idCount; // how many images?
ICONDIRENTRY idEntries[1]; // the entries for each image
} ICONDIR, *LPICONDIR; //ICON文件数据存储格式
typedef struct
{
BITMAPINFOHEADER icheader; // dib header
RGBQUAD iccolors[1]; // color table
byte icxor[1]; // dib bits for xor mask
byte icand[1]; // dib bits for and mask
} iconimage, *lpiconimage;
 
(1)格式具体的讲解可以参考一下两篇文章:ICON格式解析ICON文件格式分析VB实现,中间涉及到BMP文件BITMAPINFOHEADER的格式解析,
可以到MSDN上或者百度上查找一下 很容易理解,ICON填充这个格式的时候和BMP文件不同,biHeight参数是ICONDIRENTRY结构中bheight的2倍,
原因是图像数据中包含了icxor和icand部分。ICon文件中比较纠结的还有ICONDIRENTRY结构中dwbytesinres和dwimageoffset这两个变量的
的计算,下文会给出具体的计算方式代码,需要自己理解一下。
(2)ICON文件的操作主要涉及读和写两部分,图标的修改则直接操作内存数据即可,注意的是里面如果内部包含多份数据,需要全部进行修改,
本文主要处理ICON文件中只有一份数据的情况。ICON文件读写可以使用C语言的FILE类型操作,C++的fstream或者ifstream以及ofstream类
以及 文件句柄CreateFile进行操作,这里使用C++的方式进行操作
(3)结构中变长变量的理解,ICONDIR结构中采用了变长数组结构,如ICONDIRENTRY idEntries[1],刚开始还有点不熟悉,这种结构默认
结构中有一个ICONDIRENTRY 变量,但是如果有多个的话可以通过重新分配内存大小来实现,具体方式参考代码中读数据部分。很囧的是,
我现在才知道C99已经支持变长数组了。
(4)数据操作代码(支持多分数据)
程序里面对ICON读入的数据重新进行了整理,结构如下
//图像数据存储
struct stImageData
{
BITMAPINFOHEADER icheader; // ptr to header
byte* icxor ;
byte* icand ; stImageData()
{
icand = NULL ;
icxor = NULL ;
}
}; //ICON图像整体组成
struct stIconData
{
int num ;
stImageData data[1];
stIconData()
{
num = 0 ;
}
}; struct stIcon
{
ICONDIR *dir ;
stIconData *icon ; stIcon()
{
dir = NULL ;
icon = NULL ;
}
};

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
读数据:
bool CIconOperate::ReadIcon(const string _str)
{
fstream fin ;
fin.open(_str.c_str(),ios_base::binary | ios_base::in);
if (!fin.is_open())
{
return false ;
} ICONDIR dirTemp ;
//reserved
fin.read((char*)(&dirTemp.idReserved),sizeof(WORD));
//type
fin.read((char*)(&dirTemp.idType),sizeof(WORD));
//num
fin.read((char*)(&dirTemp.idCount),sizeof(WORD)); //image data header
byte *pBuffer = new byte[3 * sizeof(WORD) + dirTemp.idCount * sizeof(ICONDIRENTRY)] ; // 变长数据操作
m_IconDir = (ICONDIR *)(pBuffer);
m_IconDir->idCount = dirTemp.idCount ;
m_IconDir->idReserved = dirTemp.idReserved ;
m_IconDir->idType = dirTemp.idType ;
for (int i = 0 ; i < dirTemp.idCount ; ++i)
{
fin.read((char*)(&m_IconDir->idEntries[i]),sizeof(ICONDIRENTRY));
} //img data
byte *pBufferData = new byte[sizeof(int) + dirTemp.idCount * sizeof(stImageData)];
m_IconData = (stIconData*)pBufferData ;
m_IconData->num = m_IconDir->idCount ;
for (int i = 0 ; i < m_IconDir->idCount ; ++ i)
{
//SEEK
fin.seekg(m_IconDir->idEntries[i].dwimageoffset,ios_base::beg) ; //READ BITMAPINFOHEADER
fin.read((char*)(&m_IconData->data[i].icheader),sizeof(BITMAPINFOHEADER)); //READ XOR DATA
int xornum = WIDTHBYTES(m_IconDir->idEntries[i].bwidth,m_IconDir->idEntries[i].wbitcount)
* m_IconDir->idEntries[i].bheight;
int andnum = WIDTHBYTES(m_IconDir->idEntries[i].bwidth,1)
* m_IconDir->idEntries[i].bheight; m_IconData->data[i].icxor = new byte[xornum];
fin.read((char*)(m_IconData->data[i].icxor),xornum); //READ AND DATA
m_IconData->data[i].icand = new byte[andnum];
fin.read((char*)(m_IconData->data[i].icand),andnum);
} fin.close(); return true ;
}

写数据

bool CIconOperate::SaveIcon(const string _str)
{
if (m_IconDir == NULL || m_IconData == NULL)
return false ; //int width = 64 ;
//int heigth = 64 ;
//int ppx = 32 ; fstream fout;
fout.open(_str.c_str(),ios_base::out | ios_base::binary); //reserved
WORD wData = 0 ;
fout.write((char*)(&wData),sizeof(WORD));
//type
wData = 1 ;
fout.write((char*)(&wData),sizeof(WORD));
//num
wData = m_IconDir->idCount ;
fout.write((char*)(&wData),sizeof(WORD)); //write ICONDIRENTRY数据
for (int i = 0 ; i < m_IconDir->idCount ; ++i)
{
//ICONDIRENTRY结构
ICONDIRENTRY iconData ;
iconData.bwidth = m_IconDir->idEntries[i].bwidth ;
iconData.bheight = m_IconDir->idEntries[i].bheight ;
iconData.bcolorcount = 0;
iconData.breserved = 0 ;
iconData.wplanes = 1 ;
iconData.wbitcount = m_IconDir->idEntries[i].wbitcount ;
iconData.dwbytesinres = sizeof(BITMAPINFOHEADER)
+ iconData.bheight * WIDTHBYTES(iconData.bwidth,iconData.wbitcount)
+ iconData.bheight * WIDTHBYTES(iconData.bwidth,1);
iconData.dwimageoffset = CalculateImageOffset(i) ; fout.write((char*)(&iconData),sizeof(ICONDIRENTRY));
} for (int i = 0 ; i < m_IconDir->idCount ; ++i)
{
//BITMAPINFOHEADER结构
BITMAPINFOHEADER tBitHeader;
tBitHeader.biSize = sizeof(BITMAPINFOHEADER);
tBitHeader.biWidth = m_IconDir->idEntries[i].bwidth ;
tBitHeader.biHeight = m_IconDir->idEntries[i].bheight*2 ;
tBitHeader.biPlanes = 1 ;
tBitHeader.biBitCount = m_IconDir->idEntries[i].wbitcount ;
tBitHeader.biCompression = 0 ;
tBitHeader.biSizeImage = 0;
tBitHeader.biXPelsPerMeter = 0 ;
tBitHeader.biYPelsPerMeter = 0 ;
tBitHeader.biClrUsed = 0 ;
tBitHeader.biClrImportant = 0 ; fout.write((char*)(&tBitHeader),sizeof(BITMAPINFOHEADER)); fout.write((char*)m_IconData->data[i].icxor,tBitHeader.biHeight/2 * WIDTHBYTES(tBitHeader.biWidth,tBitHeader.biBitCount)); fout.write((char*)m_IconData->data[i].icand,tBitHeader.biHeight/2 * WIDTHBYTES(tBitHeader.biWidth,1)); } fout.close(); return true ;
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
2快捷方式搜索
以前没注意到这个问题,原来快捷方式也是有具体格式的,格式后缀为.LNK,格式的具体解析可以参考文档:lnk文件解析windows快捷方式
在程序中windows系统提供了IshellLink类进行具体的操作,OK,文件搜索的windows系统通过IShellForder来继续操作,具体搜索过程可以
参考文章:Windows Shell提取媒体信息vC++实现遍历桌面和快速启动里的所有快捷方式, ok,这些理解之后,你就可以遍历桌面的所有快捷
方式了。还需要理解一下window的注册表操作,桌面的位置是通过注册表获得的。
vector<string>* CFileSearch::SearchLinkByName(const CString& _str)
{
m_FindList.clear();
m_strFind = _str ; GetPath(m_strDeskTopPath,m_strQuickLanchPath);
if(GetDesktopIShellFolder())
{
GetIEunmIDList(m_pIShellFolder,FALSE,m_mode);
} fprintf(fp,"\n\n\n\n");
for (int i = 0 ; i < m_FindList.size() ; i++)
{
fprintf(fp,"%s\n",m_FindList[i].c_str());
}
return &m_FindList ;
} //获取桌面文件夹和快速启动文件夹的路径
int CFileSearch::GetPath(char *DeskTop, char* AppData)
{
CRegKey m_reg;
if(ERROR_SUCCESS==m_reg.Open(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",KEY_READ))
{
ULONG m_ulsize1=1000;
ULONG m_ulsize2=1000;
m_reg.QueryStringValue("Desktop",DeskTop,&m_ulsize1);
m_reg.QueryStringValue("AppData",AppData,&m_ulsize2);
lstrcat(AppData,"\\Microsoft\\Internet Explorer\\Quick Launch"); }
return 0;
} //获取桌面文件夹的IShellFolder接口指针
BOOL CFileSearch::GetDesktopIShellFolder()
{
m_pIShellFolder=GetIShellFolderByPath(m_strDeskTopPath);
//m_pAppData=GetIShellFolderByPath(m_strQuickLanchPath);
return TRUE;
} //获取桌面文件夹的IEnumIDList接口
//isQuickLanch---是否搜索第二层文件夹
//isRecur---是否是文件夹
BOOL CFileSearch::GetIEunmIDList(IShellFolder * pShellFolder,BOOL isRecur,BOOL isQuickLanch)
{
IEnumIDList *pIEnumFile = NULL ;
IEnumIDList *pIEnumFolder = NULL ; if(!pShellFolder)
return FALSE; HRESULT hr=pShellFolder->EnumObjects(0,SHCONTF_NONFOLDERS,&pIEnumFile); //不是文件夹
if(FAILED(hr))
{
return FALSE;
}
if(!isRecur)
{
m_pFirstLayerFile = pIEnumFile;
}
EnumAllItems(pIEnumFile,FALSE,isQuickLanch); if(!isQuickLanch)
{
HRESULT hr=pShellFolder->EnumObjects(0,SHCONTF_FOLDERS,&pIEnumFolder); //文件夹
if(FAILED(hr))
{
return FALSE;
} if(!isRecur)
{
m_pFirstLayerFolder = pIEnumFolder;
} EnumAllItems(pIEnumFolder,TRUE,isQuickLanch);
}
return TRUE;
} BOOL CFileSearch::EnumAllItems(IEnumIDList *m_pEnum,BOOL isFolder,BOOL isQuickLanch)
{
LPITEMIDLIST m_pItem=NULL;
ULONG m_ulwork= 0;
while(m_pEnum->Next(1,&m_pItem,&m_ulwork)==S_OK)
{
//如果是第一层,重置路径
if(!isQuickLanch)
{
if((m_pFirstLayerFolder==m_pEnum) && (isFolder))
{
lstrcpy(m_strParentPath,m_strDeskTopPath);
} if((m_pFirstLayerFile==m_pEnum) && (!isFolder))
{
lstrcpy(m_strParentPath,m_strDeskTopPath);
}
}
else
{
// if((m_pFirstLayerFile==m_pEnum) && (!isFolder))
// {
// lstrcpy(m_strParentPath,m_strQuickLanchPath);
// }
if((m_pFirstLayerFolder==m_pEnum) && (isFolder))
{
lstrcpy(m_strParentPath,m_strDeskTopPath);
} if((m_pFirstLayerFile==m_pEnum) && (!isFolder))
{
lstrcpy(m_strParentPath,m_strDeskTopPath);
}
} WIN32_FIND_DATA ffd;
SHGetDataFromIDList(m_pIShellFolder,m_pItem,SHGDFIL_FINDDATA,&ffd,sizeof(WIN32_FIND_DATA));
if(!isFolder)
{
CString m_strTempPath=m_strParentPath;
m_strTempPath+="\\";
m_strTempPath += ffd.cFileName;
CString m_strCmp=".lnk"; fprintf(fp,"%s\n",m_strTempPath.GetBuffer());
m_strTempPath.MakeUpper();
m_strCmp.MakeUpper(); if(m_strTempPath.Right(4)==m_strCmp) //判断是否是链接文件
{
if (ReadShortCut(m_strTempPath.GetBuffer()))
{
string str = m_strTempPath.GetBuffer();
m_FindList.push_back(str);
}
m_strTempPath.ReleaseBuffer();
}
}
else
{
lstrcat(m_strParentPath,"\\");
lstrcat(m_strParentPath,ffd.cFileName);
IShellFolder *m_pITemp=GetIShellFolderByPath(m_strParentPath);
GetIEunmIDList(m_pITemp,TRUE,isQuickLanch);
}
}
return TRUE;
} //获取指定目录的IShellFolder接口
IShellFolder *CFileSearch::GetIShellFolderByPath(LPTSTR path)
{
IShellFolder *m_ShellFolderTopMost=NULL;
HRESULT hr=SHGetDesktopFolder(&m_ShellFolderTopMost);
if(FAILED(hr))
{
return NULL;
}
IShellFolder *m_pFolder;
LPITEMIDLIST pidlWorkDir=NULL;
OLECHAR strOleFilePath[MAX_PATH];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, path, -1, strOleFilePath, MAX_PATH );
hr = m_ShellFolderTopMost->ParseDisplayName(NULL,NULL,strOleFilePath,NULL,&pidlWorkDir,NULL);
if(FAILED(hr))
{
return NULL;
}
hr=m_ShellFolderTopMost->BindToObject(pidlWorkDir,NULL,IID_IShellFolder,(LPVOID*)&m_pFolder);
if(m_ShellFolderTopMost)m_ShellFolderTopMost->Release();
return m_pFolder;
} //读取快捷方式的信息
BOOL CFileSearch::ReadShortCut(LPTSTR linkName)
{
::CoInitialize(NULL);
IShellLink *m_pIShellLink=NULL;
IPersistFile *m_pIPersistFile=NULL;
HRESULT hr=::CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&m_pIShellLink);
if(hr==S_OK)
{
hr=m_pIShellLink->QueryInterface(IID_IPersistFile,(void **)&m_pIPersistFile); if(hr==S_OK)
{
USES_CONVERSION;
m_pIPersistFile->Load(T2COLE(linkName),STGM_READWRITE); char m_strPath[MAX_PATH]={0};
m_pIShellLink->GetPath(m_strPath,MAX_PATH,NULL,SLGP_UNCPRIORITY); CString temp = m_strPath;
temp.MakeUpper(); m_strFind.MakeUpper(); if (strstr(temp.GetBuffer(),m_strFind.GetBuffer())) //判断应用程序名
{
//AfxMessageBox(temp); if(m_pIShellLink)
m_pIShellLink->Release(); if(m_pIPersistFile)
m_pIPersistFile->Release(); ::CoUninitialize();
return TRUE;
}
}
} if(m_pIShellLink)
m_pIShellLink->Release(); if(m_pIPersistFile)
m_pIPersistFile->Release(); ::CoUninitialize();
return FALSE;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
3快捷方式图标的更新
 搜索到快捷方式之后,IshellLink类提供了更换图标、设置描述、设置链接的应用程序等信息,如果要参考文档可以参考一下:
快捷方式操作指南在应用程序中创建快捷方式
 
 bool CModifyLinkICon::ChangeLinkIcon(const string& strLnkName,const string& strIconPath)
{
if (strLnkName.empty() || strIconPath.empty())
{
return false;
} HRESULT hres;
IShellLink *psl = NULL;
IPersistFile *pPf = NULL;
int id;
LPITEMIDLIST pidl;
bool bRet = false; do
{
hres = CoInitialize(NULL);
if (FAILED(hres))
{
break;
} hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (FAILED(hres))
{
break;
} hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&pPf);
if (FAILED(hres))
{
break;
} wchar_t wsz[256];
MultiByteToWideChar(CP_ACP, 0, strLnkName.c_str(), -1, wsz, MAX_PATH); hres = pPf->Load(wsz, STGM_READWRITE);
if (FAILED(hres))
{
break;
} hres = psl->SetIconLocation(strIconPath.c_str(), 0);
if (FAILED(hres))
{
break;
} pPf->Save(wsz, TRUE);
if (FAILED(hres))
{
break;
} bRet = true; } while (0); if (pPf != NULL)
{
pPf->Release();
} if (psl != NULL)
{
psl->Release();
} CoUninitialize(); AfxMessageBox("替换完成"); return bRet;
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

4结论

其实这些操作估计很早之前就有,网上的信息页很多,我就算做一下汇总吧,最后给出我测试用的界面,很简答,可以实现快捷的搜索,快捷图标的更换,图像的读取,写入以及简单的修改。


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

ICON文件保存的更多相关文章

  1. Python 获取 exe 的 icon 并且保存

    Python 获取 exe 的 icon 并且保存 参考链接:https://mail.python.org/pipermail/python-win32/2009-April/009078.html ...

  2. java 文件保存到本地

    private void savePic(InputStream inputStream, String fileName) { OutputStream os = null; try { Strin ...

  3. C# 文件选择对话框,Unity3d文件保存对话框

    using OpenWinForm = System.Windows.Forms; 在unity3d中,使用FileDialog应该把System.Windows.Forms.dll拷贝到unity工 ...

  4. 怎么直接让火狐输入json数据,而不是弹出文件保存对话框?

    一.问题再现: 我需要浏览器输出的是json数据,但是浏览器弹出的是一个文件保存的对话框,这样的体验有点差.所以想怎么让浏览器直接输出到浏览器的页面上面,并且格式的输出,还可以编辑. 测试数据: ht ...

  5. php 下载保存文件保存到本地的两种方法

    第一种: 1 <? ?> 或 <?php //下载文件保存到本地//www.jbxue.comfunction downfile($fileurl){ob_start(); $fil ...

  6. 使用CURL下载远程文件保存到服务器

    比如微信公众平台开发,下载用户的头像到服务器上: /** * 使用CURL获取远程文件保存到服务器 *@param $image=$oJSON->headimgurl; 获取到的微信返回的头像U ...

  7. (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法

    FPGA管脚分配文件保存方法 使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里. 方法一: 查看引脚绑定情况,quartus -> assignment ...

  8. 【转】warning C4819,该文件保存为 Unicode 格式以防止数据丢失,处理方法

    以下的解决方案只是把错误给屏蔽掉而已,并不能真正解决这个警告.仅供参考! 当项目引用到外部源代码后,经常出现4819错误,警告信息如下: warning C4819: 该文件包含不能在当前代码页(93 ...

  9. php动态网页实现页面静态化 通过在初次被访问时生成html文件保存起来,下次该PHP程序被访问时就直接找到以前被访问过的html页面

    一.什么是静态页面?什么是动态页面 静态页面是网页的代码都在页面中,不需要执行asp,php,jsp,.net等程序生成客户端网页代码的网页.不能   静态页面 动态页面 区别:           ...

随机推荐

  1. repo sync下载脚本

    #!/bin/sh echo "======start repo sync======" repo sync while [ $? -ne 0 ]do echo "=== ...

  2. Linux下打包压缩war和解压war包

    Linux下打包压缩war和解压war包 unzip是一种方法,如果不行则采用下面的方法 把当前目录下的所有文件打包成game.war jar -cvfM0 game.war ./ -c   创建wa ...

  3. java写入文件的几种方法分享

    转自:http://www.jb51.net/article/47062.htm 一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所 ...

  4. InputStream的三个read的区别

    转自:http://www.blogjava.net/toby/archive/2009/04/24/267413.html 1.read这个方法是对这个流一个一个字节的读,返回的int就是这个字节的 ...

  5. Linux常用命令_(文件权限)

    Linux权限管理: 二.权限管理1.3种基本权限在Linux中,将使用系统资源的人员分为4类:超级用户.文件或目录的属主.属主的同组人和其他人员.超级用户拥有对Linux系统一切操作权限,对 于其他 ...

  6. 简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea

    题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /******* ...

  7. 状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely

    题目传送门 题意:有n*m的房间,'.'表示可以被点亮,'#'表示不能被点亮,每点亮一个房间会使旁边的房间也点亮,有意盏特别的灯可以选择周围不同方向的房间点亮.问最少需要多少灯使得所有房间点亮 分析: ...

  8. HDU2222 Keywords Search(AC自动机模板)

    AC自动机是一种多模式匹配的算法.大概过程如下: 首先所有模式串构造一棵Trie树,Trie树上的每个非根结点都代表一个从根出发到该点路径的字符串. 然后每个结点都计算出其fail指针的值,这个fai ...

  9. hdu Oil Deposits

    因为这道题中给的数据比较小,所以可以直接用枚举的方式进行dfs搜索,每出现一个‘@’,就进行一次dfs的搜索,将所有相邻的‘@’全部变成‘*’. #include"iostream" ...

  10. html5文章 -- 使用 jQuery Mobile 与 HTML5 开发 Web App ——开发原则 | Kayo's Melody

    最近专注研究 jQuery Mobile —— 一款很方便就可以把 Web App 包装成适合 Android 与 iPhone 等触屏移动设备的 Javascript 库,结合 jQuery Mob ...