当前位置:   article > 正文

【windows核心编程】 4 进程

4号进程

 

 

【1】

windows程序分为GUI程序好CUI程序,即Graphical User Interface和Console User Interface

在Visual Studio中,GUI程序的链接开关是/SUBSYSTEM:WINDOWS, GUI程序的链接开关是/SUBSYSTEM:CONSOLE

这是一个控制台程序的设置。

 

windows程序的入口有以下两种:

  1. 1 Int WINAPI _tWinMain(
  2. 2 HINSTANCE hInstanceExe, //进程实例句柄
  3. 3 HINSTANCE , /*hPreInstance*/ //之前的实例,总为NULL
  4. 4 PTSTR, pszCmdLine, //命令行参数,包括exe名称
  5. 5 int nCmdShow
  6. 6 );
  7. 7
  8. 8
  9. 9
  10. 10 int _tmain(
  11. 11 int argc, //参数个数,包含exe
  12. 12 TCHAR *argv[], //每个参数字符串
  13. 13 TCHAR *envp[] //进程环境变量指针数组
  14. 14 );

 

 

【2】

但是在调用上述入口函数之前,系统会调用真正的入口函数来做一些初始化的工作,比如初始化全局变量和静态C++对象的构造,下面说明了每种情况下的真正的入口函数

 

ANSI--------_tWinMain(WinMain)------------WinMainCRTStartup

UNICODE---_tWinMain(wWinMain)-----------wWinMainCRTStartup

ANSI--------_tmain(Main)--------------------mainCRTStartup

UNICODE----_tmain(wMain)------------------wmainCRTStartup

 上面四个真正的入口函数的源码在C运行库的crtexe.c文件中。

 

 

【3】

HINSTANCE和HMODULE相同,可相互替代,只是在16位windows时代有所不同。

加载到进程地址空间的每个可执行文件和DLL都有一个唯一的实例句柄, HICON LoadIcon(HINSTANCE  hInstance, PCTSTR pszZIcon)函数的作用是从实例句柄为hInstance的文件中加载名为pszIcon的图标资源。

可执行文件的实例被当作(w)WinMain函数的第一个参数(见上文),即参数 hInstanceExe, 这个参数的实际值是一个内存基地址,希望将可执行文件的映像加载到进程地址空间中的这个位置。

Visual Studio连接器默认的基地址是0x00400000, 这是在win98下,可执行文件所能加载到的最低的地址。使用MS的连接器/BASE:address开关可以更改基地址。

那么怎么样获得一个可执行文件或DLL被加载到进程地址空间的什么位置呢? 可用下函数:

HMODULE  GetModuleHandle(PCTSTR  pszModule)

加入A进程调用了一个可执行文件B和一个DLL名为C, 那么可以用这个函数来把B 或 C的名字作为pszModule参数传给它取得B或C在当前进程地址空间中的位置, 如果找到了该参数标明的可执行文件或DLL,那么将返回他们在进程地址空间中的位置,否则返回NULL。

如果给pszModule参数传NULL, 那么将返回调用此函数的进程即A进程的可执行文件的基地址。

 

  1. 1 #include "stdafx.h"
  2. 2 #include <iostream>
  3. 3 #include "windows.h"
  4. 4
  5. 5 int _tmain(int argc, _TCHAR* argv[])
  6. 6 {
  7. 7
  8. 8 HMODULE hModue = GetModuleHandle(NULL);
  9. 9
  10. 10 printf("当前进程地址为:0x%08x\n", hModue);
  11. 11
  12. 12 PWSTR lpParams = GetCommandLineW(); //取得命令行参数,包括exe
  13. 13
  14. 14 int count = 0;
  15. 15
  16. 16 PWSTR *pRet = CommandLineToArgvW(lpParams, &count); //命令行参数和参数个数,包括exe; 该函数内部分配内存, 返回指针数组(指针的指针)
  17. 17
  18. 18 for (int i = 0; i < count; ++ i)
  19. 19 {
  20. 20 std::wcout<<pRet[i]<<std::endl;
  21. 21 }
  22. 22
  23. 23
  24. 24 return 0;
  25. 25 }

 

输出如下:

 

需要注意的是:上面函数CommandLineToArgvW在函数内部分配内存,且不释放,一般情况下是可以接收的,但是如果想要手动释放那部分内存也是可以的

HeapFree函数可以用来释放那部分内存:

HeapFree(GetProcessHeap(), 0, pRet);   //pRet为上面CommandLineToArgvW函数的返回值。

 

 

  1. 1 PTSTR pszValue = NULL;
  2. 2
  3. 3 DWORD dwResult = GetEnvironmentVariable(_T("path"), pszValue, 0);
  4. 4
  5. 5 if (0 != dwResult)
  6. 6 {
  7. 7 pszValue = (PTSTR)malloc(size);
  8. 8 GetEnvironmentVariable(_T("path"), pszValue, size);
  9. 9 wcout<<pszValue<<endl;
  10. 10
  11. 11 free(pszValue);
  12. 12 }

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/926461/blog/350932

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/69306
推荐阅读
相关标签
  

闽ICP备14008679号