Artigo: 196070 - Última revisão: terça-feira, 21 de Novembro de 2006 - Revisão: 4.2

Como fazer com que a criação de perfil de um utilizador através de programação

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Este artigo demonstra como programaticamente fazer com que um perfil de utilizador a ser criado sem ser necessário um início de sessão interactivo.

Mais Informação

Por predefinição, um novo perfil de utilizador não é criado até que o utilizador iniciar sessão no computador interactivamente. Um início de sessão interactivo ocorre quando um utilizador inicia sessão no computador, premindo CTRL + ALT + DEL para ter acesso através da caixa de diálogo WinLogon.

É possível fazer com que um perfil de utilizador a ser criado sem ser necessário um início de sessão interactivo ao chamar a API LoadUserProfile() programaticamente. No Windows 2000 e Windows XP, esta função é exposta nos ficheiros de cabeçalho Platform SDK e documentada na MSDN Library. No Windows NT 4.0, a API LoadUserProfile() não está exposta, mas ainda pode ser chamado ao carregar a biblioteca Userenv.dll dinamicamente e obter um apontador para a função.

chamar LoadUserProfile() no Windows NT 4.0

Este artigo demonstra como trabalhar com as estruturas de perfil de utilizador e funções no Windows NT 4.0. Para informações completas sobre estes estruturas e funções, consulte a documentação Platform SDK na versão mais recente da MSDN Library.

A estrutura PROFILEINFO

A estrutura PROFILEINFO fornece informações sobre um perfil de utilizador:
   typedef struct _PROFILEINFO {
       DWORD   dwSize;          // size of structure
       DWORD   dwFlags;         // flags
       LPTSTR  lpUserName;      // user name
       LPTSTR  lpProfilePath;   // roaming profile path
       LPTSTR  lpDefaultPath;   // default user profile path
       LPTSTR  lpServerName;    // validating domain controller name
       LPTSTR  lpPolicyPath;    // Windows NT 4.0-style policy file
       HANDLE  hProfile;        // registry key handle
   } PROFILEINFO, FAR * LPPROFILEINFO;
				
dwSize Especifica o tamanho de estrutura, em bytes.

dwFlags pode ser um dos seguintes sinalizadores:
PI_NOUI (1)--impede a apresentação das mensagens de erro de perfil.
PI_APPLYPOLICY (2)--aplica-se uma política de estilo 4.0 do Windows NT.
lpUserName é um apontador para o nome do utilizador.

lpProfilePath é um apontador para o caminho do perfil guardado no servidor.

lpDefaultPath é um apontador para o caminho do perfil de utilizador predefinido.

lpServerName é um apontador para o nome do controlador de domínio validar, no formato de NetBIOS.

lpPolicyPath é um apontador para o caminho do ficheiro de política.

hProfile conterá o identificador da chave de registo HKEY_CURRENT_USER após regressar com êxito.

A função LoadUserProfile()

A função LoadUserProfile() carrega o perfil do utilizador especificado. Se o perfil ainda não existir, o sistema operativo criará-lo. O autor da chamada tem de ter privilégios administrativos no computador.
   BOOL LoadUserProfile(
     HANDLE hToken,
     LPPROFILEINFO lpProfileInfo
   );

   hToken is a token for the user. The token must have TOKEN_IMPERSONATE
   access.

   lpProfileInfo is a pointer to a PROFILEINFO structure.
				
se a função tiver êxito, o valor devolvido é diferente de zero. Se a função falhar, o valor devolvido é zero. Para obter informações de erro expandidas, ligue GetLastError().

Após regressar com êxito, o membro hProfile de PROFILEINFO é um identificador de chave de registo aberto para a raiz do ramo do utilizador. Não feche a alça de hProfile. Passá-las em vez disso, para a função UnloadUserProfile() .

A função UnloadUserProfile()

A função UnloadUserProfile descarrega um perfil de utilizador que foi carregado pela função LoadUserProfile . O autor da chamada tem de ter privilégios administrativos no computador.
   BOOL UnloadUserProfile(
     HANDLE hToken,
     HANDLE hProfile
   );
				
hToken é um token do utilizador. O token tem de ter acesso TOKEN_IMPERSONATE.

hProfile é o membro hProfile da estrutura PROFILEINFO após uma chamada com êxito para LoadUserProfile().
Se a função tiver êxito, o valor devolvido é diferente de zero. Se a função falhar, o valor devolvido é zero. Para obter informações de erro expandidas, ligue GetLastError().

A função GetUserProfileDirectory()

A função GetUserProfileDirectory devolve o caminho para o directório raiz do perfil do utilizador especificado.
   BOOL GetUserProfileDirectory(
     HANDLE  hToken,
     LPTSTR lpProfileDir,
     LPDWORD lpcchSize
   );
hToken é um token do utilizador. O token tem de ter acesso TOKEN_IMPERSONATE.

lpProfilesDir é um ponteiro para a memória intermédia que recebe o caminho para directório de perfil do utilizador especificado.

lpcchSize Especifica o tamanho do buffer lpProfilesDir, em bytes.
Se a função tiver êxito, o valor devolvido é diferente de zero. Se a função falhar, o valor devolvido é zero. Para obter informações de erro expandidas, ligue GetLastError().

Código de exemplo

O código de exemplo abaixo pode ser compilado como uma aplicação de consola para o Windows NT 4.0. Esta abordagem mesma irá funcionar no Windows 2000 e Windows XP, mas normalmente seria mais fácil de incluir o ficheiro de cabeçalho userenv.h e uma hiperligação directamente com a biblioteca userenv.lib. Ligar implícito é preferível porque não é necessário carregar a DLL dinamicamente e obter apontadores para funções para as APIs de perfil de utilizador.

Este código demonstra como programaticamente criar uma nova conta de utilizador, forçar um perfil a ser criado para o novo utilizador e obter o novo directório de perfil:
   //**********************************************************************
   // 
   //  This program creates a new user account, forces a profile to be
   //  created for the new user, and retrieves the new profile directory
   // 
   //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
   //  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
   //  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
   //  PARTICULAR PURPOSE.
   // 
   //  Copyright (C) 1998 Microsoft Corporation. All rights reserved.
   //  Author: Jonathan Russ (jruss)
   // 
   //**********************************************************************

   // NOTE: This code must be linked with netapi32.lib

   #include <windows.h>
   #include <tchar.h>
   #include <stdio.h>
   #include <lm.h>

   // Declarations based on USERENV.H for Windows 2000 Beta 2
   #define PI_NOUI         0x00000001   // Prevents displaying of messages
   #define PI_APPLYPOLICY  0x00000002   // Apply NT4 style policy

   typedef struct _PROFILEINFO {
      DWORD    dwSize;          // Must be set to sizeof(PROFILEINFO)
      DWORD    dwFlags;         // See flags above
      LPTSTR   lpUserName;      // User name (required)
      LPTSTR   lpProfilePath;   // Roaming profile path
      LPTSTR   lpDefaultPath;   // Default user profile path
      LPTSTR   lpServerName;    // Validating DC name in netbios format
      LPTSTR   lpPolicyPath;    // Path to the NT4 style policy file
      HANDLE   hProfile;        // Registry key handle - filled by function
   } PROFILEINFO, FAR * LPPROFILEINFO;

   // Typedefs for function pointers in USERENV.DLL
   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
      HANDLE hToken,
      LPPROFILEINFO lpProfileInfo
   );

   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
      HANDLE hToken,
      HANDLE hProfile
   );

   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
      HANDLE hToken,
      LPTSTR lpProfileDir,
      LPDWORD lpcchSize
   );

   HMODULE                 g_hUserEnvLib           = NULL;
   LPFNLOADUSERPROFILE     LoadUserProfile         = NULL;
   LPFNUNLOADUSERPROFILE   UnloadUserProfile       = NULL;
   LPFNGETUSERPROFILEDIR   GetUserProfileDirectory = NULL;


   //**********************************************************************
   // 
   //  FUNCTION:     InitUserEnv - This function dynamically links to
   //                USERENV.DLL and sets up the required function pointers
   // 
   //  PARAMETERS:   none
   // 
   //  RETURN VALUE: TRUE if successful. Otherwise, FALSE.
   // 
   //**********************************************************************

   BOOL InitUserEnv( void ) {

      g_hUserEnvLib = LoadLibrary( _T("userenv.dll") );
      if ( !g_hUserEnvLib ) {
         _tprintf( _T("LoadLibrary(userenv.dll) failed.  Error %d\n"),
              GetLastError() );
         return FALSE;
      }

   #ifdef UNICODE
      LoadUserProfile =
            (LPFNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "LoadUserProfileW" );
   #else
      LoadUserProfile =
            (LPFNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "LoadUserProfileA" );
   #endif

      if (!LoadUserProfile) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "LoadUserProfile", GetLastError() );
         return FALSE;
      }

      UnloadUserProfile =
            (LPFNUNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "UnloadUserProfile" );

      if (!UnloadUserProfile) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "UnloadUserProfile", GetLastError() );
         return FALSE;
      }

   #ifdef UNICODE
      GetUserProfileDirectory =
            (LPFNGETUSERPROFILEDIR) GetProcAddress( g_hUserEnvLib,
            "GetUserProfileDirectoryW" );
   #else
      GetUserProfileDirectory =
            (LPFNGETUSERPROFILEDIR) GetProcAddress( g_hUserEnvLib,
            "GetUserProfileDirectoryA" );
   #endif

      if (!GetUserProfileDirectory) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "GetUserProfileDirectory", GetLastError() );
         return FALSE;
      }

      return TRUE;
   }


   //**********************************************************************
   // 
   //  FUNCTION:     _tmain - This is the entry point for the program.
   // 
   //  PARAMETERS:   argc - the number of command-line arguments
   //                argv - an array of null-terminated strings specifying
   //                       the command-line arguments
   //                envp - an array of null-terminated strings specifying
   //                       the environment strings
   // 
   //  RETURN VALUE: Zero if successful. Otherwise, non-zero.
   // 
   //**********************************************************************

   #ifdef __cplusplus
      extern "C"
   #endif

   #ifdef UNICODE
      int _cdecl
   #else
      int
   #endif

   _tmain(int argc, _TCHAR **argv, _TCHAR **envp) {

      USER_INFO_1   ui1;
      DWORD         dwError;
      HANDLE        hToken;
      PROFILEINFO   pi;
      TCHAR         szProfilePath[1024];
      DWORD         cchPath = 1024;
      WCHAR         szUserName[20];
      WCHAR         szPassword[20];

      // Check for the required command-line arguments
      if (argc < 2) {
         _tprintf( _T("Usage: AddUser <user> [password]\n") );
         return -1;
      }

      // Set USERENV.DLL function pointers
      if ( !InitUserEnv() ) {
         _tprintf( _T("Failed to set USERENV.DLL function pointers.\n") );
         return -1;
      }

      // Create local copies of the user name and password
      #ifdef UNICODE

      _tcscpy( szUserName, argv[1] );
      if ( argc == 2 ) {
         _tcscpy( szPassword, szUserName );
      } else {
         _tcscpy( szPassword, argv[2] );
      }

      #else
      {
         int n;

         n = MultiByteToWideChar(0, 0, argv[1], -1, szUserName, 20);
         if (n == 0)
         {
            _tprintf( _T("Failed to convert username to unicode\n"));
            return -1;
         }

         if ( argc == 2 ) {
            n = MultiByteToWideChar(0, 0, argv[1], -1, szPassword, 20);
         } else {
            n = MultiByteToWideChar(0, 0, argv[2], -1, szPassword, 20);
         }
         if (n == 0)
         {
            _tprintf( _T("Failed to convert password to unicode\n"));
            return -1;
         }
      }
      #endif

      // Set up the USER_INFO_1 structure that will be used to create the
      // new user account
      ZeroMemory( &ui1, sizeof(ui1) );
      ui1.usri1_name = szUserName;
      ui1.usri1_password = szPassword;
      ui1.usri1_priv = USER_PRIV_USER;
      ui1.usri1_flags = UF_NORMAL_ACCOUNT | UF_SCRIPT;

      // Create the new user account
      dwError = NetUserAdd(
            NULL,            // target computer name
            1,               // info level
            (LPBYTE) &ui1,   // address of user info structure
            NULL );          // index to invalid parameter
      if ( dwError != NERR_Success ) {
         _tprintf( _T("NetUserAdd() failed.  Error %d\n"), dwError );
         dwError = ERROR_ACCESS_DENIED;
         return -1;
      }

      // Do a network logon because most systems do not grant new users
      // the right to logon interactively (SE_INTERACTIVE_LOGON_NAME)
      // but they do grant the right to do a network logon
      // (SE_NETWORK_LOGON_NAME). A network logon has the added advantage
      // of being quicker.

      // NOTE: To call LogonUser(), the current user must have the
      // SE_TCB_NAME privilege
      if ( !LogonUser(
            argv[1],                        // user name
            _T("."),                        // domain or server
            (argc == 2) ? argv[1]:argv[2],  // password
            LOGON32_LOGON_NETWORK,          // type of logon operation
            LOGON32_PROVIDER_DEFAULT,       // logon provider
            &hToken ) ) {                   // pointer to token handle
         _tprintf( _T("LogonUser() failed.  Error %d\n"), GetLastError() );
         return -1;
      }

      // Set up the PROFILEINFO structure that will be used to load the
      // new user's profile
      ZeroMemory( &pi, sizeof(pi) );
      pi.dwSize = sizeof(pi);

      #ifdef UNICODE
      pi.lpUserName = szUserName;
      #else
      pi.lpUserName = argv[1];
      #endif

      pi.dwFlags = PI_NOUI;

      // Load the profile. Since it doesn't exist, it will be created
      if ( !LoadUserProfile(
            hToken,        // token for the user
            &pi ) ) {      // pointer to PROFILEINFO structure
         _tprintf( _T("LoadUserProfile() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }

      // Unload the profile when it is no longer needed
      if ( !UnloadUserProfile(
            hToken,              // token for the user
            pi.hProfile ) ) {    // registry key handle
         _tprintf( _T("UnloadUserProfile() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }

      // Retrieve the new user's profile directory
      if ( !GetUserProfileDirectory( hToken, szProfilePath, &cchPath ) ) {
         _tprintf( _T("GetProfilePath() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }

      // Display the new user's profile directory
      _tprintf( _T("The new user's profile path is %s\n"), szProfilePath );

      // Release USERENV.DLL
      if ( g_hUserEnvLib ) {
         FreeLibrary( g_hUserEnvLib );
      }

      return 0;
   }
				

A informação contida neste artigo aplica-se a:
  • Microsoft Win32 Application Programming Interface nas seguintes plataformas
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
Palavras-chave: 
kbmt kbcode kbhowto kbkernbase KB196070 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 196070  (http://support.microsoft.com/kb/196070/en-us/ )