我们知道一般的Windows程序都会有一个WinMain函数,Chrome的这个函数在chrome\app\chrome_exe_main_win.cc这个文件中:

 
  
  1. int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {   
  2.   // Initialize the commandline singleton from the environment.   
  3.   CommandLine::Init(0, NULL);   
  4.   // The exit manager is in charge of calling the dtors of singletons.   
  5.   base::AtExitManager exit_manager;  
  6.   
  7.   MetroDriver metro_driver;   
  8.   if (metro_driver.in_metro_mode())   
  9.     return metro_driver.RunInMetro(instance, &RunChrome);   
  10.   // Not in metro mode, proceed as normal.   
  11.   return RunChrome(instance);   
  12. }  

首先,这个函数初始化了CommandLine,它是一个singleton,用来保存和管理当前进程中的所有参数。然后又创建了一个AtExitManager,它是用来负责所有singleton的销毁工作的。若是在Win8下并满足MetroDriver的检测的话,就可能通过MetroDriver::RunInMetro来启动Chrome。下面将详细看一下用的比较多的RunChrome函数。

 
  
  1. int RunChrome(HINSTANCE instance) {   
  2.   bool exit_now = true;   
  3.   // We restarted because of a previous crash. Ask user if we should relaunch.   
  4.   if (ShowRestartDialogIfCrashed(&exit_now)) {   
  5.     if (exit_now)   
  6.       return content::RESULT_CODE_NORMAL_EXIT;   
  7.   }  
  8.   
  9.   // Initialize the sandbox services.   
  10.   sandbox::SandboxInterfaceInfo sandbox_info = {0};   
  11.   content::InitializeSandboxInfo(&sandbox_info);  
  12.   
  13.   // Load and launch the chrome dll. *Everything* happens inside.   
  14.   MainDllLoader* loader = MakeMainDllLoader();   
  15.   int rc = loader->Launch(instance, &sandbox_info);   
  16.   loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded();   
  17.   delete loader;   
  18.   return rc;   

RunChrome中的第一个先调用ShowRestartDialogIfCrashed,Chrome若是之前崩溃了,这个函数就互弹出一个MessageBox,告诉你崩溃的情况,是否需要再开启Chrome,若要开启,下面的代码再跑一遍,重新打开Chrome。

接下来初始化sandbox,sandbox对象创建完后,必须要用content::InitializeSandboxInfo初始化。

由于,Chrome的实际内容并不在Chrome.exe中,而在Chrome.dll中,所以下面有个创建MainDllLoader对象的过程 —— MakeMainDllLoader()。然后通过这个对象的Launch方法将整个Chrome加载起来,这个方法有两个参数:一个是WinMain中的HINSTANCE,另一个是之前创建的那个sandbox。

 
  
  1. int MainDllLoader::Launch(HINSTANCE instance,   
  2.                           sandbox::SandboxInterfaceInfo* sbox_info) {   
  3.   string16 version;   
  4.   string16 file;   
  5.   dll_ = Load(&version, &file);   
  6.   if (!dll_)   
  7.     return chrome::RESULT_CODE_MISSING_DATA;  
  8.   
  9.   scoped_ptr<base::Environment> env(base::Environment::Create());   
  10.   env->SetVar(chrome::kChromeVersionEnvVar, WideToUTF8(version));  
  11.   
  12.   InitCrashReporter();   
  13.   OnBeforeLaunch(file);  
  14.   
  15.   DLL_MAIN entry_point =   
  16.       reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll_, "ChromeMain"));   
  17.   if (!entry_point)   
  18.     return chrome::RESULT_CODE_BAD_PROCESS_TYPE;  
  19.   
  20.   int rc = entry_point(instance, sbox_info);   
  21.   return OnBeforeExit(rc, file);   
  22. }  

这个函数中,先通过Load方法将Chrome.dll加载进来,dll_中保存了DLL句柄,下面还有其他一些准备工作。接着在GetProcAddress这里进入正题了,寻找Chrome.dll这个模块中名为ChromeMain的函数,entry_point中保存了这个函数指针,最后通过调用这个函数进到Chrome.dll模块中执行剩余的工作。