这两天想做一下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. linux下安装pymssql

    WIN下安装PYMSSQL,由于我没有系统管理权限,无法安装, 那只好在LINUX下面安装罗.. 以下这个文章帮助我搞定. http://blog.csdn.net/five3/article/det ...

  2. IIS上发布WCF发布服务,访问不到

    1 环境是IIS7,发布WCF发布服务,访问不到. 一种原因站点自动生成“程序应用池”和站点的Framwork版本不一致. 解决的办法:新建一个“程序应用池”,然后站点指向这个新建的“程序应用池”

  3. hihoCoder挑战赛14 -1223

    描述 给定n个关于X的不等式,问最多有多少个成立. 每个不等式为如下的形式之一: X < C X <= C X = C X > C X >= C 输入 第一行一个整数n. 以下 ...

  4. JeeWx 微信管家平台

    .平台简介 Jeewx是一款开源.免费的微信管家系统(多触点管理平台),2014年荣获CSDN开发商大会第一名.采用JAVA语言,支持微信公众号.微信企业号.支付宝服务窗等多触点管理.Jeewx实现了 ...

  5. Servlet应用的运行流程

    其中,红色部分为我们开发人员要做的,其他部分是框架做的. 学习就要搞懂整个运行的流程!否则,不利于个人技术的积累!

  6. Listview点击事件

    listview = (ListView) findViewById(R.id.listview); // 填充data数据 data = new ArrayList<String>(); ...

  7. exec命令

    exec 命令实例 find . -name "*.cc" -exec grep -P -n -H --color=auto "[^\w]main[^\w]" ...

  8. VMware Tools安装

    不是每一个程序员都必须玩过linux,只是博主觉得现在的很多服务器都是linux系统的,而自己属于那种前端也搞,后台也搞,对框架搭建也感兴趣,但是很多生产上的框架和工具都是安装在服务器上的,而且有不少 ...

  9. js:语言精髓笔记1--标识符与基本类型

    标识符: 命名: 语法以及类型----语法关键字                                           //逻辑 值(的存储位置)----变量和常量           ...

  10. http://jingyan.baidu.com/article/db55b609aac41e4ba30a2f86.html

    http://jingyan.baidu.com/article/db55b609aac41e4ba30a2f86.html