zoukankan      html  css  js  c++  java
  • Windows创建的基本含义和进程的进程的内核

    过程

    1 这意味着过程:

    1.1   一个是在操作系统的内核对象管理处理。

    的统计信息的地方。

    1.2   还有一个是地址空间。它包括全部可运行模块或DL L 模块的代码和数据。它还包括动态内存分配的空间。如线程堆栈和堆分配空间。

    2 操作系统启动应用程序的步骤

    2.1 调用C/c++执行时的启动函数

             启动函数总共4种,WinMainCRTStartup,wWinMainCRTStartup,mainCRTStartup,wmainCRTStartup。

             启动函数完毕例如以下任务:

    <1>检索指向新进程的完整命令行的指针

    <2>检索指向新进程的环境变量的指针

    <3>对C/ C + +执行期的全局变量进行初始化。

    假设包括了S t d L i b . h 文件。代码就能訪问这些变量

    <4>对C执行期内存单元分配函数(m a l l o c 和c a l l o c )和其它低层输入/输出例程使用的内存栈进行初始化。

    <5>为全部全局和静态C+ +类对象调用构造函数。

    <6>调用入口点函数

    如:int nMainRetVal = wmain(__argc, __wargv, _wenviron); 

    <7>当进入点函数返回时,启动函数便调用C 执行期的ex i t 函数,将返回值(nMainRetVal )传递给它。

    <8>调用由_onexit函数的调用而注冊的不论什么函数

    <9>为全部全局的和静态的C++类对象调用析构函数

    <10>调用操作系统的ExitProcess函数。将nMainRetVal传递给它。

    这使得该操作系统可以撤消进程并设置它的e x i t 代码

    3 进程的实例句柄

    3.1 进程的当前实例句柄

             载入到进程地址空间的每一个exe或者dll文件都会被赋予一个独一无二的句柄。

    获取载入的模块(exe,dll)的方法:

    GetModuleFileName(HMOUDLEhModule,LPTSTR lpFileName,DWROD nSize);

    当hModule的值为NULL 的时候。会返回当前调用模块的所有路径名字。

    3.2 进程的前一个实例句柄

             C++代码总是将NULL赋值给WinMain函数的第二个參数HINSTANCEhPreInstance,这种原因是在16位的程序中对这个參数有保留使用,那么保留它就方便转用16位程序。

    4 进程的命令行

    LPTSTR GetCommandLine();获取命令行字符串

    5  进程的环境变量

             每一个进程都有一个与它相关的环境变量块,环境块是进程的地址空间中分配的一个内存块。每一个环境块都包括一组字符串,形式例如以下所看到的:

    VarName1=VarValue1

    VarName2=VarValue2

    VarName3=VarValue3

             当中要注意变脸等号前有没有空格。有空格和没空格代表的是全然不同的环境变量,如:

    XYZ=xxx;和XYZ =xxx;这就是两个全然不同的环境变量了。

             操作华景变量相关的 函数

    <1>

    LPVOIDGetEnvironmentStrings(VOID);

    <2>

    BOOL SetEnvironmentVariable(
     LPCTSTR lpName,  // environment variable name
     LPCTSTR lpValue  // new value for variable);

    <3>

    DWORD GetEnvironmentVariable(  LPCTSTR lpName,  // environment variable name
     LPTSTR lpBuffer, // buffer for variable value
     DWORD nSize      // size ofbuffer);

    <4>

    BOOL FreeEnvironmentStrings(LPTSTRlpszEnvironmentBlock  // environmentstrings);

    6 进程的当前文件夹

             程序的当前文件夹是能够进行改变的。当前文件夹和进程的启动文件夹是不同的,启动文件夹就是exe或者dll被调用的文件夹,我们能够通过GetModuleFineName函数进行处理。

    <1>

    DWORD GetCurrentDirectory(
     DWORD nBufferLength,    //size of directory buffer
     LPTSTR lpBuffer            //directory buffer);

    <2>

    BOOL SetCurrentDirectory(  LPCTSTR lpPathName   // new directory name);

    7 系统的版本号信息获得

    GetVersion()

    可是这个函数有bug,就是程序猿把主版本。次版本放错了高低字节。

    BOOL GetVersionEx(  LPOSVERSIONINFO lpVersionInfo // versioninformation);

    这个是新的修正过来的。

    8 创建进程

    BOOL WINAPI CreateProcess(
      _In_opt_     LPCTSTR lpApplicationName,
      _Inout_opt_   LPTSTR lpCommandLine,
      _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
      _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
      _In_         BOOL bInheritHandles,
      _In_         DWORD dwCreationFlags,
      _In_opt_     LPVOID lpEnvironment,
      _In_opt_     LPCTSTR lpCurrentDirectory,
      _In_         LPSTARTUPINFO lpStartupInfo,
      _Out_        LPPROCESS_INFORMATION lpProcessInformation
    );


    參数解释:

    <1> lpApplicationName

             被载入模块的名字,必须制定模块的格式。比方exe,由于系统不会默觉得exe,模块的名字能够是部门名字,那么系统就会在当前文件夹去寻找该模块。

             通常将其设置为NULL。由于lpCommandLine具有比它更加强大的功能来完毕模块的调用。

    <2> lpCommandLine

             系统寻找可运行文件exe的顺序是:

    应用程序载入的文件夹。

    父进程的当前文件夹;

    Windows System 文件夹;

    Windows文件夹。

    环境变量列出的文件夹;

    注意:当字符集是Unicode时候,參数类型不能是const类型的,若是就会报错。

    <3> lpProcessAttributes 

           指向 SECURITY_ATTRIBUTES的指针,决定进程创建函数返回的的新进程对象的句柄能否被子进程继承。

             当为NULL的时候,获取的是默认安全描写叙述符

    <4> lpThreadAttributes

           指向SECURITY_ATTRIBUTES 的指针,决定进程创建函数范湖的新线程对象的句柄能否被子进程继承。

             当为NULL的时候。获取的是默认安全描写叙述符。

    <5> bInheritHandles 

           假设为True。那么不论什么能够被继承的句柄都会别新创建的进程所继承。假设为FALSE。那么则不会被新进程继承。

    <6>dwCreationFlags 

           新创建的进程的创建标志位设置,决定是父子进程调试信息的反馈,子进程窗体的产生等行为。

    <7> lpEnvironment 

    新进程中指向的环境块。假设该值为NULL。那么就表示新进程继承了父进程的环境块。

    <8>lpCurrentDirectory 

    指向新进程的当前文件夹的指针。假设为NULL。那么则就和调用进程(父进程)具有同样的当前文件夹。

    <9> lpStartupInfo

           指向 STARTUPINFO or STARTUPINFOEX的指针。

    主要指定窗体的状态。外观,标准句柄。

    当Wi n d o w s 创建新进程时。它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序只使用默认值。至少应该将该结构中的全部成员初始化为零,然后将cb 成员设置为该结构的大小。

           当里面创建的句柄不在是用的使用,要通过CloseHandle来关闭。

    <10> lpProcessInformation 

    指向PROCESS_INFORMATION结构体的指针。

    typedef struct _PROCESS_INFORMATION {
      HANDLE hProcess;
      HANDLE hThread;
      DWORD  dwProcessId;
      DWORD  dwThreadId;
    } PROCESS_INFORMATION, *LPPROCESS_INFORMATION;


    里面是用的句柄不在使用的时候。要通过CloseHandle函数来关闭。

           当进程内核对象创建后,系统赋予该对象一个独一无二的标识号。系统中的其它不论什么进程内核对象都不能使用这个同样的ID号。线程内核对象的情况也一样。当一个线程内核对象创建时,该对象被赋予一个独一无二的、系统范围的ID号。进程ID和线程ID共享同样的号码池。

    这意味着进程和线程不可能拥有同样的ID 。


    9 创建进程的实例:

    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    void main()
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );
    
        // Start the child process. 
        if( !CreateProcess( NULL, // No module name (use command line). 
            TEXT("Notepad++"),	// Command line. 
            NULL,             // Process handle not inheritable. 
            NULL,             // Thread handle not inheritable. 
            FALSE,            // Set handle inheritance to FALSE. 
            0,                // No creation flags. 
            NULL,             // Use parent's environment block. 
            NULL,             // Use parent's starting directory. 
            &si,              // Pointer to STARTUPINFO structure.
            &pi )             // Pointer to PROCESS_INFORMATION structure.
        ) 
        {
            cout<<TEXT("CreateProcess failed.");
        }
    
        // Wait until child process exits.
        WaitForSingleObject( pi.hProcess, INFINITE );
    
        // Close process and thread handles. 
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }
    



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Allegro PCB Design GXL (legacy) 使用slide无法将走线推挤到焊盘的原因
    OrCAD Capture CIS 16.6 导出BOM
    Altium Designer (17.0) 打印输出指定的层
    Allegro PCB Design GXL (legacy) 将指定的层导出为DXF
    Allegro PCB Design GXL (legacy) 设置十字大光标
    Allegro PCB Design GXL (legacy) 手动更改元器件引脚的网络
    magento产品导入时需要注意的事项
    magento url rewrite
    验证台湾同胞身份证信息
    IE8对css文件的限制
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4643359.html
Copyright © 2011-2022 走看看