久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

通過資源文件方式打包exe、腳本,、dll文件為單個(gè)exe文件的解決方案

 londonKu 2012-04-29
想將Lua和腳本文件打包成一個(gè)exe文件,,以便發(fā)布,從網(wǎng)上查了N多資源,,終于搞定了^-^
主要實(shí)現(xiàn)方案是通過將Lua解釋器和腳本文件以資源文件中RCDATA類型打包進(jìn)exe文件中,,在運(yùn)行文件時(shí)再 進(jìn)行釋放,然后在臨時(shí)目錄中執(zhí)行,。

大概步驟為:
1,、編寫相應(yīng)的rc文件,添加想打包的所有文件
2,、通過FindResource\SizeofResource\LoadResource\LockResource四個(gè)函數(shù)查找定位exe打包文件中對(duì) 應(yīng)的各個(gè)資源文件,,并創(chuàng)建至臨時(shí)目錄中
3、用CreateProcess\WaitForSingleObject\CloseHandle三個(gè)函數(shù)實(shí)現(xiàn)run and wait功能(好像 GetExitCodeProcess的方式也行)
4,、等程序執(zhí)行完畢,,刪除臨時(shí)文件
(5、LoadLibrary\GetProcAddress\CallWindowProc\FreeLibrary四個(gè)函數(shù)實(shí)現(xiàn)ActiveX dll的注冊(cè))

該方案一個(gè)缺點(diǎn)是可能容易被殺軟認(rèn)為是病毒-_-||
實(shí)現(xiàn)該功能的一個(gè)簡(jiǎn)單方案為使用專業(yè)軟件,,如PEBundle,。。,。

更新歷史:
      2008-11-4: 改動(dòng)較多,目前可以釋放到"temp","current","system","windows"和指定目錄下了,,并 且解決了運(yùn)行腳本時(shí)工作目錄不一定為當(dāng)前exe文件所在目錄的問題。增加了部分目錄處理函數(shù)和字符串 處理函數(shù)。
      2008-11-3: 看了一位大大的blog,,其使用pe文件的形式實(shí)現(xiàn)了動(dòng)態(tài)加載到內(nèi)存中執(zhí)行,,等有時(shí)間時(shí) 好好研究研究,http://blog.csdn.net/lisunlin0/
      2008-11-1: 添加ActiveX dll的注冊(cè)函數(shù)DllRegister的實(shí)現(xiàn),;將RunWait中的GetTempFilePath提取 出來,,以便通用;在一個(gè)字符串前添加一個(gè)空格寫為函數(shù),。
      2008-10-31: 初次版本釋放,,主要為ResourceFile_Create,RunWait,,ResourceFile_Delete三個(gè)函 數(shù)

對(duì)應(yīng)的代碼如下:

/*相應(yīng)的rc資源文件代碼 - data.rc*/
IDR_LUA RCDATA "lua.exe"
IDR_SCRIPT RCDATA "script.lua"
IDR_UNICODE RCDATA "Unicode.dll"

/*相應(yīng)的C代碼 - OneEXE.c*/
#include <stdio.h>
#include <windows.h>

/*將給定的兩個(gè)字符串連接起來,,并返回為一個(gè)新的字符串*/
char* StringJoin(const char* first,const char* last)
{
     char* result;
     int len = strlen(first)+strlen(last)+1;
     result = (char*)malloc(len*sizeof(char));
     memset(result,0,len*sizeof(char));
     strcpy(result,first);
     strcat(result,last);
     return result;
}
/*獲取字符串指定部分*/
char* StringSub(const char* string,int start,int number)
{
      int len = strlen(string);
      char* temp;
      if(start>len)
      {
          printf("Start %d is too big than string length %d!\n",start,len);
          return NULL;
      }
      if(number>(len-start))
      {
          printf("Number is too big!\n");
          number = len - start + 1;
      }
      temp = (char*)malloc(sizeof(char)*(number+1));
      memset(temp,0,(number+1)*sizeof(char));

      int i = 0;
      int j = 0;
      while(i != number)
          temp[i++] = string[(start-1)+j++];
      temp[number]='\0';

      return temp;
}
/*用StringJoin函數(shù),在字符串末尾添加'\'*/
char* add_slash(char* string)
{
     int len = strlen(string);
     /*查看最后一個(gè)字符是否為'\'*/
     if(string[len-1] != '\\')
         return StringJoin(string,"\\");
     else
         return string;
}
/*獲取臨時(shí)目錄*/
char* TempPath()
{
      char *Buffer;
      DWORD dwRet;
      /*獲取臨時(shí)目錄*/
      /*獲取臨時(shí)目錄字符串大小,,包含末尾的'\0'*/
      dwRet    = GetTempPath(0,NULL);
      if( dwRet == 0 )
      {
          printf("GetCurrentDirectory failed (%d)\n", GetLastError());
          return NULL;
      }
      /*根據(jù)獲取的空間,,分配內(nèi)存,并置零*/
      Buffer = (char *)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      /*獲取臨時(shí)目錄*/
      GetTempPath(dwRet,Buffer);
      return add_slash(Buffer);
}
/*獲取當(dāng)前工作目錄*/
char* CurrentPath()
{
      char *Buffer;
      DWORD dwRet;
      /*獲取當(dāng)前目錄*/
      /*獲取當(dāng)前目錄字符串大小,,包含末尾的'\0'*/
      dwRet    = GetCurrentDirectoryA (0,NULL);
      if( dwRet == 0 )
      {
          printf("GetCurrentDirectory failed (%d)\n", GetLastError());
          return NULL;
      }
      /*根據(jù)獲取的空間,,分配內(nèi)存,并置零*/
      Buffer = (char *)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      /*獲取臨時(shí)目錄*/
      GetCurrentDirectoryA (dwRet,Buffer);
      return add_slash(Buffer);
}
/*獲取系統(tǒng)System32目錄*/
char* SystemPath()
{
      char *Buffer;
      DWORD dwRet;
      /*獲取System目錄*/
      /*獲取System目錄字符串大小,,包含末尾的'\0'*/
      dwRet    = GetSystemDirectoryA (NULL,0);
      if( dwRet == 0 )
      {
          printf("GetCurrentDirectory failed (%d)\n", GetLastError());
          return NULL;
      }
      /*根據(jù)獲取的空間,,分配內(nèi)存,并置零*/
      Buffer = (char *)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      /*獲取臨時(shí)目錄*/
      GetSystemDirectoryA (Buffer,dwRet);
      return add_slash(Buffer);
}
/*獲取Windows目錄*/
char* WindowsPath()
{
      char *Buffer;
      DWORD dwRet;
      /*獲取Windows目錄*/
      /*獲取Windows目錄字符串大小,,包含末尾的'\0'*/
      dwRet    = GetWindowsDirectoryA (NULL,0);
      if( dwRet == 0 )
      {
          printf("GetCurrentDirectory failed (%d)\n", GetLastError());
          return NULL;
      }
      /*根據(jù)獲取的空間,,分配內(nèi)存,并置零*/
      Buffer = (char *)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      /*獲取臨時(shí)目錄*/
      GetWindowsDirectoryA (Buffer,dwRet);
      return add_slash(Buffer);
}
/*獲取當(dāng)前運(yùn)行程序的目錄*/
char* ExePath()
{
      char *Buffer;
      /*設(shè)置初始緩存大小為32*/
      DWORD size=32;
      DWORD dwRet=32;
      Buffer = (char*)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      /*獲取Windows目錄*/
      /*獲取Windows目錄字符串大小,,包含末尾的'\0'*/
      dwRet = GetModuleFileNameA(NULL,Buffer,dwRet);
      printf("%d %d\n",dwRet,size);
      if(dwRet == 0)
          return NULL;
      while (size == dwRet)
      {
          size *= 2;
          Buffer = (char*)realloc(Buffer,sizeof(char)*size);
          memset(Buffer,0,size*sizeof(char));
          dwRet = GetModuleFileNameA(NULL,Buffer,size);
          printf("%d %d\n",dwRet,size);
      }
      return Buffer;
}
/*獲取一個(gè)指定文件的目錄*/
char* GetDir(const char* filepath)
{
      char* pos = strrchr(filepath,'\\');
      if(pos == NULL)
          return NULL;
      else
          return StringSub(filepath,1,pos + 1 - filepath);
}
/*設(shè)置文件路徑*/
char* SetFilePath(const char* name,const char* path)
{
      char* filepath;
      if(strcmp(path,"temp")==0)
          filepath = StringJoin(TempPath(),name);
      else if (strcmp(tolower(path),"current")==0)
          /*該實(shí)現(xiàn)可能出現(xiàn)問題,似乎為父進(jìn)程工作目錄
          filepath = StringJoin(CurrentPath(),name);*/
          filepath = StringJoin(GetDir(ExePath()),name);
      else if (strcmp(tolower(path),"system")==0)
          filepath = StringJoin(SystemPath(),name);
      else if (strcmp(tolower(path),"windows")==0)
          filepath = StringJoin(WindowsPath(),name);
      else
          filepath = add_slash(StringJoin(path,name));
      return filepath;
}
/*定位自己的資源文件,,并將其創(chuàng)建至系統(tǒng)臨時(shí)目錄*/
int ResourceFile_Create(const char* ID,const char* name,const char* path)
{     HRSRC hr;
      DWORD dwSize, dwWritten;
      HGLOBAL hg;
      LPSTR lp;
      HANDLE hFile;
      /*讀入資源文件,四步:
        1.FindResource
        2.SizeofResource
        3.LoadResource
        4.LockResource
       */
      /*定位自定義資源,,由于是從本模塊定位資源,,所以將句柄簡(jiǎn)單地置為NULL即可,
        第二個(gè)參數(shù)為定義ID字符串,,為函數(shù)的第一個(gè)參數(shù),,第三個(gè)為定義的類型,這里全部默認(rèn)定義為 RT_RCDATA*/
      hr=FindResource(NULL,ID,RT_RCDATA);
      /*查找資源文件失敗的處理*/
      if(hr==NULL)
      {
          MessageBox (NULL, TEXT ("hr error"),TEXT ("Error"), MB_OK);
          return -1;
      }
      /*獲取資源大小*/
      dwSize=SizeofResource(NULL,hr);
      /*讀入資源文件*/
      hg=LoadResource(NULL,hr);
      /*讀入資源失敗時(shí)的處理*/
      if(hg==NULL)
      {
          MessageBox (NULL, TEXT ("hg error"),TEXT ("Error"), MB_OK);
          return -1;
      }
      /*鎖定資源*/
      lp=(LPSTR)LockResource(hg);
      /*鎖定資源失敗的處理*/
      if(lp==NULL)
      {
          MessageBox (NULL, TEXT ("lp error"),TEXT ("Error"), MB_OK);
          return -1;
      }
      /*獲取指定文件夾目錄路徑*/
      char* filepath=SetFilePath(name,path);
      /*在指定目錄創(chuàng)建文件*/
      hFile = CreateFile(filepath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
      /*創(chuàng)建文件失敗的處理*/
      if(hFile == NULL)
      {
          MessageBox (NULL, TEXT ("Create file error!"),TEXT ("Error"), MB_OK);
          return -1;
      }
      /*將資源文件寫入指定目錄路徑*/
      WriteFile(hFile,(LPCVOID)LockResource(hg),dwSize,&dwWritten,NULL);
      CloseHandle(hFile);
      return 0;
}
/*在一個(gè)字符串前加一個(gè)空格,,以便下邊的RunWait中CreateProcess第二個(gè)參數(shù)命令行使用*/
char* addblank(const char* string )
{
      char *string_blank;
      string_blank = (char*)malloc(strlen(string)+2);
      sprintf(string_blank," %s",string);
      return string_blank;
}
/*獲取一個(gè)文件的短路徑,,如果不存在該文件,則返回NULL*/
char* ShortPath(char* Path)
{
      char *Buffer;
      DWORD dwRet;
      dwRet = GetShortPathNameA(Path,NULL,0);
      if(dwRet == 0)
          return NULL;
      Buffer = (char*)malloc(sizeof(char)*dwRet);
      memset(Buffer,0,dwRet*sizeof(char));
      GetShortPathNameA(Path,Buffer,dwRet);
      return Buffer;
}
/*運(yùn)行文件及命令,,并等待其退出*/
int RunWait(const char* app,const char* cmdline)
{
      /*初始化*/
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      ZeroMemory( &si, sizeof(si) );
      si.cb = sizeof(si);
      ZeroMemory( &pi, sizeof(pi) );

      /*開始執(zhí)行,,參數(shù)2在字符串前加了一個(gè)空格*/
      /*函數(shù)倒數(shù)第三個(gè)函數(shù)設(shè)置為當(dāng)前exe文件的目錄,表示其工作目錄為exe文件目錄*/
      if(!CreateProcess(ShortPath(app),addblank(ShortPath(cmdline)), NULL, NULL, FALSE, 0,   NULL, GetDir(ExePath()), &si, &pi))
      {
          char error_string[128];
          sprintf(error_string,"Create Process failed (%d)",GetLastError());
          MessageBox (NULL, TEXT (error_string),TEXT ("Error"), MB_OK);
          return -1;
      }
      /*等待結(jié)束*/
      WaitForSingleObject( pi.hProcess, INFINITE );
      /*結(jié)束句柄*/
      CloseHandle( pi.hProcess );
      CloseHandle( pi.hThread );
      return 0;
}
/*注冊(cè)或者反注冊(cè)Dll文件*/
int DllRegister(const char* file,const char* func)
{
      /*主要通過
      1、LoadLibrary
      2、GetProcAddress
      3,、CallWindowProc
      4,、FreeLibrary這4個(gè)函數(shù)進(jìn)行處理*/
      HINSTANCE handle;
      typedef int (CALLBACK* LPFNDLLFUNC)(int,int);
      LPFNDLLFUNC lpfnDllFunc;
      /*讀入dll文件*/
      handle = LoadLibrary(file);
      if( handle != NULL )
      {
          /*通過GetProcAddress獲取函數(shù)func地址*/
          lpfnDllFunc = (LPFNDLLFUNC)GetProcAddress(handle,func);
          if( lpfnDllFunc != NULL )
          {
              /*調(diào)用函數(shù)*/
              CallWindowProc((WNDPROC)lpfnDllFunc,(HWND)handle,0,0,0);
          }
          else
          {
              MessageBox (NULL, TEXT ("The function is invalid!"),TEXT ("Error"), MB_OK);
              return -1;
          }
          /*釋放資源*/
          FreeLibrary(handle);
      }
      else
      {
          MessageBox (NULL, TEXT ("The dll is invalid!"),TEXT ("Error"), MB_OK);
          return -1;
      }
      return 0;
}
/*刪除釋放的資源文件*/
int ResourceFile_Delete(const char* name,const char* path)
{
      BOOL check;
      /*設(shè)置文件路徑*/
      char* filepath=SetFilePath(name,path);;

      /*刪除文件并驗(yàn)證是否成功*/
      check = DeleteFile(filepath);
      char error_string[128];
      sprintf(error_string,"Can't delete the file - %s",name);
      if(!check)
      {
          MessageBox (NULL, TEXT (error_string),TEXT ("Error"), MB_OK);
          return -1;
      }
      return 0;
}
/*主程序*/
int APIENTRY WinMain(
          HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPSTR       lpCmdLine,
          int         nCmdShow)
{
      /*釋放臨時(shí)資源文件*/
      ResourceFile_Create("IDR_LUA","lua.exe","temp");
      ResourceFile_Create("IDR_SCRIPT","script.lua","temp");
      ResourceFile_Create("IDR_Unicode","Unicode.dll","temp");    
      /*注冊(cè)dll,僅僅ActiveX dll需要注冊(cè),,假定Unicode.dll為ActiveX dll*/
      DllRegister(SetFilePath("Unicode.dll","temp"),"DllRegisterServer");
      /*運(yùn)行腳本*/
      RunWait(SetFilePath("lua.exe","temp"),SetFilePath("script.lua","temp"));
      /*反注冊(cè)dll*/
      DllRegister(SetFilePath("Unicode.dll","temp"),"DllUnregisterServer");
      /*刪除臨時(shí)資源文件*/
      ResourceFile_Delete("lua.exe","temp");
      ResourceFile_Delete("script.lua","temp");
      ResourceFile_Delete("Unicode.dll","temp");

      return 0;
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多