|
@@ -0,0 +1,439 @@
|
|
|
+// lyfzRename.cpp : 定义控制台应用程序的入口点。
|
|
|
+//
|
|
|
+
|
|
|
+#include "stdafx.h"
|
|
|
+#include "rename.h"
|
|
|
+#include <Shlwapi.h>
|
|
|
+#include <io.h>
|
|
|
+#include "PARAMETERS.h"
|
|
|
+
|
|
|
+#ifdef _DEBUG
|
|
|
+#define new DEBUG_NEW
|
|
|
+#endif
|
|
|
+
|
|
|
+HMODULE g_hCurModule = NULL;
|
|
|
+TCHAR g_szCurModulePath[MAX_PATH] = {0};
|
|
|
+TCHAR g_szFna[MAX_PATH] = {0};
|
|
|
+
|
|
|
+BOOL GetDebugPriv();
|
|
|
+void WriteTextLog(const TCHAR *format, ...);
|
|
|
+string GetFileVersion(const string &strFilePath);
|
|
|
+bool GetFileVersion(IN const TCHAR *fname, IN HMODULE hModule, OUT WORD *pBuffer);
|
|
|
+bool GetProductVersion(IN const TCHAR *fname, IN HMODULE hModule, OUT WORD *pBuffer);
|
|
|
+void getopt(PARAMETERS & params, int argc, char ** argv);
|
|
|
+// 唯一的应用程序对象
|
|
|
+
|
|
|
+CWinApp theApp;
|
|
|
+
|
|
|
+using namespace std;
|
|
|
+
|
|
|
+int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
|
+{
|
|
|
+ int nRetCode = 0;
|
|
|
+ TCHAR szDrive[_MAX_DRIVE] = { 0 };
|
|
|
+ TCHAR szDir[_MAX_DIR] = { 0 };
|
|
|
+ TCHAR szFna[_MAX_DIR] = { 0 };
|
|
|
+ TCHAR szExt[_MAX_DIR] = { 0 };
|
|
|
+ ::GetModuleFileName(NULL, g_szCurModulePath, sizeof(g_szCurModulePath) / sizeof(TCHAR));
|
|
|
+ _tsplitpath_s(g_szCurModulePath, szDrive, szDir, g_szFna, szExt);
|
|
|
+ _tcscpy_s(g_szCurModulePath, szDrive);
|
|
|
+ _tcscat_s(g_szCurModulePath, szDir);
|
|
|
+
|
|
|
+ GetDebugPriv();
|
|
|
+ // 初始化 MFC 并在失败时显示错误
|
|
|
+ if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
|
|
|
+ {
|
|
|
+ // TODO: 更改错误代码以符合您的需要
|
|
|
+ _tprintf(_T("错误: MFC 初始化失败\n"));
|
|
|
+ nRetCode = 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 获取参数;
|
|
|
+ PARAMETERS params;
|
|
|
+ getopt(params, argc, argv);
|
|
|
+#ifdef _DEBUG
|
|
|
+ WriteTextLog(_T("%ld, %ld,%s,%s"),params.dwProcId, params.killproc, params.NewVerPath.c_str(), params.OldVerPath.c_str());
|
|
|
+#endif
|
|
|
+ if ( params.dwProcId != 0)
|
|
|
+ {
|
|
|
+ // 等待进程退出;
|
|
|
+ DWORD dwTargetProId = 0;
|
|
|
+ HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, params.dwProcId);
|
|
|
+ if ( hProc != NULL)
|
|
|
+ {
|
|
|
+ if ( params.killproc )
|
|
|
+ {//结束进程;
|
|
|
+ TerminateProcess(hProc, 0);
|
|
|
+ Sleep(500);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 等待线程结束;
|
|
|
+ WaitForSingleObject(hProc, INFINITE);
|
|
|
+ CloseHandle(hProc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!PathFileExists(params.NewVerPath.c_str()))
|
|
|
+ {
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+#if 0//以主程序为升级包的处理方法;
|
|
|
+ // 删除旧版本文件;
|
|
|
+ DeleteFile(params.OldVerPath.c_str());
|
|
|
+ // 移动文件;
|
|
|
+ MoveFile(params.NewVerPath.c_str(), params.OldVerPath.c_str());
|
|
|
+
|
|
|
+ if ( params.killproc )
|
|
|
+ {
|
|
|
+ // 启动程序;
|
|
|
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);//某些情况下要初始化COM才能使用ShellExecuteEx;
|
|
|
+ SHELLEXECUTEINFO stuExecInfo = { 0 };
|
|
|
+ DWORD dwExitCode = STILL_ACTIVE;
|
|
|
+ stuExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
|
|
+ stuExecInfo.lpFile = params.OldVerPath.c_str();
|
|
|
+ stuExecInfo.nShow = SW_SHOW;
|
|
|
+ stuExecInfo.lpVerb = _T("open");
|
|
|
+ stuExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
|
|
|
+
|
|
|
+ if (!ShellExecuteEx(&stuExecInfo))
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ WriteTextLog(_T("ShellExecuteEx Error=%ld"), dwError);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ HANDLE hProcess = stuExecInfo.hProcess;
|
|
|
+ if ( hProcess != NULL )
|
|
|
+ {
|
|
|
+ //WaitForSingleObject(hProcess,INFINITE);//不等待结束;
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#else//以安装包为升级包的处理方法;//可以选择静默安装安装包;
|
|
|
+ if ( params.killproc )
|
|
|
+ {
|
|
|
+ // 启动程序;
|
|
|
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);//某些情况下要初始化COM才能使用ShellExecuteEx;
|
|
|
+ SHELLEXECUTEINFO stuExecInfo = { 0 };
|
|
|
+ DWORD dwExitCode = STILL_ACTIVE;
|
|
|
+ CString strParameters = _T("/S");
|
|
|
+ stuExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
|
|
+ stuExecInfo.lpFile = params.NewVerPath.c_str();
|
|
|
+ stuExecInfo.nShow = SW_SHOW;
|
|
|
+ //stuExecInfo.lpParameters = strParameters;//不静默安装;
|
|
|
+ stuExecInfo.lpVerb = _T("open");
|
|
|
+ stuExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
|
|
|
+
|
|
|
+ if (!ShellExecuteEx(&stuExecInfo))
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ WriteTextLog(_T("ShellExecuteEx Error=%ld"), dwError);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ HANDLE hProcess = stuExecInfo.hProcess;
|
|
|
+ if ( hProcess != NULL )
|
|
|
+ {
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nRetCode;
|
|
|
+}
|
|
|
+
|
|
|
+void getopt(PARAMETERS & params, int argc, char ** argv)
|
|
|
+{
|
|
|
+ std::string cmd = "";
|
|
|
+ for ( argc > 0; argc--; argv++ )
|
|
|
+ {
|
|
|
+ if ( _tcsicmp(*argv, _T("--pid")) == 0)
|
|
|
+ {
|
|
|
+ cmd = _T("--pid");
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(*argv, _T("--oldpath")) == 0)
|
|
|
+ {
|
|
|
+ cmd = _T("--oldpath");
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(*argv, _T("--newpath")) == 0)
|
|
|
+ {
|
|
|
+ cmd = _T("--newpath");
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(*argv, _T("--killproc")) == 0)
|
|
|
+ {
|
|
|
+ cmd = _T("--killproc");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if ( _tcsicmp(cmd.c_str(), _T("--pid")) == 0)
|
|
|
+ {
|
|
|
+ params.dwProcId = atoi(*argv);
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(cmd.c_str(), _T("--oldpath")) == 0)
|
|
|
+ {
|
|
|
+ params.OldVerPath = *argv;
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(cmd.c_str(), _T("--newpath")) == 0)
|
|
|
+ {
|
|
|
+ params.NewVerPath = *argv;
|
|
|
+ }
|
|
|
+ else if (_tcsicmp(cmd.c_str(), _T("--killproc")) == 0)
|
|
|
+ {
|
|
|
+ params.killproc = atoi(*argv);
|
|
|
+ }
|
|
|
+
|
|
|
+ cmd = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//2.获得其他exe或dll的版本信息
|
|
|
+string GetFileVersion(const string &strFilePath)
|
|
|
+{
|
|
|
+ DWORD dwSize;
|
|
|
+ DWORD dwRtn;
|
|
|
+ string szVersion;
|
|
|
+ //获取版本信息大小
|
|
|
+ dwSize = GetFileVersionInfoSize(strFilePath.c_str(),NULL);
|
|
|
+ DWORD dwErr = GetLastError();
|
|
|
+ if (dwSize == 0)
|
|
|
+ {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ char *pBuf;
|
|
|
+ pBuf= new char[dwSize + 1];
|
|
|
+ if(pBuf == NULL)
|
|
|
+ return "";
|
|
|
+ memset(pBuf, 0, dwSize + 1);
|
|
|
+ //获取版本信息
|
|
|
+ dwRtn = GetFileVersionInfo(strFilePath.c_str(),NULL, dwSize, pBuf);
|
|
|
+ if(dwRtn == 0)
|
|
|
+ {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ LPVOID lpBuffer = NULL;
|
|
|
+ UINT uLen = 0;
|
|
|
+ //版本资源中获取信息
|
|
|
+ dwRtn = VerQueryValue(pBuf,
|
|
|
+ TEXT("\\StringFileInfo\\080404b0\\FileVersion"), //0804中文
|
|
|
+ //04b0即1252,ANSI
|
|
|
+ //可以从ResourceView中的Version中BlockHeader中看到
|
|
|
+ //可以测试的属性
|
|
|
+ /*
|
|
|
+ CompanyName
|
|
|
+ FileDescription
|
|
|
+ FileVersion
|
|
|
+ InternalName
|
|
|
+ LegalCopyright
|
|
|
+ OriginalFilename
|
|
|
+ ProductName
|
|
|
+ ProductVersion
|
|
|
+ Comments
|
|
|
+ LegalTrademarks
|
|
|
+ PrivateBuild
|
|
|
+ SpecialBuild
|
|
|
+ */
|
|
|
+ &lpBuffer,
|
|
|
+ &uLen);
|
|
|
+ if(dwRtn == 0)
|
|
|
+ {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ szVersion = (char*)lpBuffer;
|
|
|
+ delete pBuf;
|
|
|
+ return szVersion;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// hModule 模块句柄 NULL表示当前模块;
|
|
|
+bool GetFileVersion(IN const TCHAR *fname, IN HMODULE hModule, OUT WORD *pBuffer)
|
|
|
+{
|
|
|
+ //TCHAR fname[MAX_PATH];
|
|
|
+ VS_FIXEDFILEINFO *pVi = NULL;
|
|
|
+ DWORD dwHandle = 0;
|
|
|
+ string str;
|
|
|
+
|
|
|
+
|
|
|
+ int size = GetFileVersionInfoSize(fname, &dwHandle);
|
|
|
+
|
|
|
+ if (size > 0)
|
|
|
+ {
|
|
|
+ BYTE *buffer = new BYTE[size];
|
|
|
+ memset(buffer,0,size);
|
|
|
+
|
|
|
+ if (GetFileVersionInfo(fname, dwHandle, size, buffer))
|
|
|
+ {
|
|
|
+ if (VerQueryValue(buffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&size))
|
|
|
+ {
|
|
|
+ pBuffer[0] = HIWORD(pVi->dwFileVersionMS);
|
|
|
+ pBuffer[1] = LOWORD(pVi->dwFileVersionMS);
|
|
|
+ pBuffer[2] = HIWORD(pVi->dwFileVersionLS);
|
|
|
+ pBuffer[3] = LOWORD(pVi->dwFileVersionLS);
|
|
|
+
|
|
|
+ delete []buffer;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ delete []buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool GetProductVersion(IN const TCHAR *fname, IN HMODULE hModule, OUT WORD *pBuffer)
|
|
|
+{
|
|
|
+ //TCHAR fname[MAX_PATH];
|
|
|
+ VS_FIXEDFILEINFO *pVi = NULL;
|
|
|
+ DWORD dwHandle = 0;
|
|
|
+ string str;
|
|
|
+
|
|
|
+
|
|
|
+ int size = GetFileVersionInfoSize(fname, &dwHandle);
|
|
|
+
|
|
|
+ if (size > 0)
|
|
|
+ {
|
|
|
+ BYTE *buffer = new BYTE[size];
|
|
|
+ memset(buffer,0,size);
|
|
|
+
|
|
|
+ if (GetFileVersionInfo(fname, dwHandle, size, buffer))
|
|
|
+ {
|
|
|
+ if (VerQueryValue(buffer, _T("\\"), (LPVOID *)&pVi, (PUINT)&size))
|
|
|
+ {
|
|
|
+ pBuffer[0] = HIWORD(pVi->dwProductVersionMS);
|
|
|
+ pBuffer[1] = LOWORD(pVi->dwProductVersionMS);
|
|
|
+ pBuffer[2] = HIWORD(pVi->dwProductVersionLS);
|
|
|
+ pBuffer[3] = LOWORD(pVi->dwProductVersionLS);
|
|
|
+
|
|
|
+ delete []buffer;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ delete []buffer;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+BOOL GetDebugPriv()
|
|
|
+{
|
|
|
+ // 返回的访问令牌指针;
|
|
|
+ HANDLE hToken;
|
|
|
+ // 接收所返回的制定特权名称的信息;
|
|
|
+ LUID sedebugnameValue;
|
|
|
+ // 新特权信息的指针(结构体);
|
|
|
+ TOKEN_PRIVILEGES tkp;
|
|
|
+ DWORD dwCurProcId = GetCurrentProcessId();
|
|
|
+ // 要修改访问权限的进程句柄;
|
|
|
+ HANDLE hCurProc;
|
|
|
+ hCurProc = ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwCurProcId );
|
|
|
+
|
|
|
+ if ( !::OpenProcessToken( hCurProc,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ //CString strError;
|
|
|
+ //strError.Format("升级包提权失败,错误码=%d",dwError);
|
|
|
+ //AfxMessageBox(strError);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! ::LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ //CString strError;
|
|
|
+ /// strError.Format("升级包提权失败,错误码=%d",dwError);
|
|
|
+ //AfxMessageBox(strError);
|
|
|
+ CloseHandle( hToken );
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1;
|
|
|
+ tkp.Privileges[0].Luid = sedebugnameValue;
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ if (!::AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
|
|
|
+ {
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ //CString strError;
|
|
|
+ //strError.Format("升级包提权失败,错误码=%d",dwError);
|
|
|
+ //AfxMessageBox(strError);
|
|
|
+ CloseHandle( hToken );
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hCurProc);
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+/************************************************************************/
|
|
|
+/* 函数:WriteTextLog[7/28/2009 Jeff];
|
|
|
+/* 描述:写文本日志;
|
|
|
+/* 参数:;
|
|
|
+/* [IN] :;
|
|
|
+/* 返回:void;
|
|
|
+/* 注意:;
|
|
|
+/* 示例:;
|
|
|
+/*
|
|
|
+/* 修改:;
|
|
|
+/* 日期:;
|
|
|
+/* 内容:;
|
|
|
+/************************************************************************/
|
|
|
+void WriteTextLog(const TCHAR *format, ...)
|
|
|
+{
|
|
|
+ // 解析出日志路径;
|
|
|
+ TCHAR szlogpath[MAX_PATH] = { 0 };
|
|
|
+ _stprintf_s(szlogpath, _T("%s%s.txt"), g_szCurModulePath, g_szFna);
|
|
|
+ // 打开或创建文件;
|
|
|
+ FILE *fp = NULL;
|
|
|
+ //if (_taccess(szlogpath, 0) != -1)
|
|
|
+#ifndef UNICODE
|
|
|
+ if (_access(szlogpath, 0) != -1)
|
|
|
+#else
|
|
|
+ if (_taccess(szlogpath, 0) != -1)
|
|
|
+#endif
|
|
|
+ {// 存在;
|
|
|
+ fp = _tfopen(szlogpath, _T("a+"));
|
|
|
+ // 移动到末尾;
|
|
|
+ fseek(fp, 0, SEEK_END);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {// 不存在;
|
|
|
+ fp = _tfopen(szlogpath, _T("w+"));
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( fp == NULL )
|
|
|
+ return;
|
|
|
+
|
|
|
+ // 格式化前设置语言区域;
|
|
|
+ TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
|
|
|
+ _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
|
|
|
+
|
|
|
+ // 格式化日志内容;
|
|
|
+ va_list args = NULL;
|
|
|
+ int len = 0;
|
|
|
+ TCHAR *buffer = NULL;
|
|
|
+ va_start(args, format);
|
|
|
+ // _vscprintf doesn't count. terminating '\0'
|
|
|
+ len = _vsctprintf(format, args) + 1;
|
|
|
+ buffer = (TCHAR*)malloc(len * sizeof(TCHAR));
|
|
|
+ _vstprintf_s(buffer, len, format, args);
|
|
|
+ // 将日志内容输入到文件中;
|
|
|
+ // 获取今年年份;
|
|
|
+ __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
|
|
|
+ struct tm gmtm = {0};
|
|
|
+ localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
|
|
|
+ _ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year+1990, gmtm.tm_mon+1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, buffer);
|
|
|
+
|
|
|
+ // 关闭文件,释放资源并设置回原语言区域;
|
|
|
+ free(buffer);
|
|
|
+ fclose(fp);
|
|
|
+ _tsetlocale(LC_CTYPE, old_locale);
|
|
|
+ free(old_locale);//还原区域设定;
|
|
|
+}
|