1. Introdução
Quando o operador erra o login no Viewer, o E3 mostra uma mensagem genérica — e só depois de algumas tentativas; nas primeiras, aparentemente nada acontece. Para dar uma resposta imediata e mais precisa (senha expirada, conta bloqueada, troca de senha obrigatória), monte uma tela de login personalizada e use o método LoginUser (ou LoginWindowsUser), lendo o código de status OpStatus. Este artigo mostra como fazer e esclarece o que é — e o que não é — possÃvel diferenciar.
2. Por que a mensagem padrão é genérica
O diálogo de login padrão (Application.Login) exibe a mesma mensagem para qualquer falha de credencial:
Login
Falha no Login.
Verifique se você informou a senha correta.
Caso o problema continue, contate o responsável pela aplicação.
Dois motivos explicam o comportamento observado:
- Número de tentativas (
LoginRetries). O diálogo padrão repete a solicitação de credenciais até esgotar o número de tentativas permitido (propriedadeLoginRetries). A mensagem de falha só aparece quando as tentativas se esgotam — por isso a 1ª e a 2ª tentativa parecem “não retornar nada”. Uma tela personalizada informa o resultado a cada tentativa. - Segurança — usuário × senha não se distingue. Para uma credencial inválida, o E3 devolve sempre o mesmo resultado, independentemente de o usuário existir ou não. Isso é proposital: informar que “esse usuário não existe” facilitaria a enumeração de usuários por um atacante. Portanto, diferenciar “erro de usuário” de “erro de senha” não é possÃvel nem recomendável.
3. O que dá para diferenciar: o código OpStatus
O LoginUser não separa usuário de senha, mas informa outras situações pelo parâmetro de saÃda OpStatus — e são essas que permitem mensagens realmente úteis:
| OpStatus | Situação | Mensagem sugerida |
|---|---|---|
0 |
Sucesso | (segue para a aplicação) |
2 |
Usuário ou senha inválidos | “Usuário ou senha inválidos.” |
4 |
Login OK, mas é obrigatório trocar a senha | “Troque a senha para continuar.” |
8 |
Senha expirada | “Sua senha expirou. Contate o responsável.” |
16 |
Conta bloqueada (excesso de tentativas) | “Conta bloqueada. Contate o responsável.” |
32 |
Conta desabilitada | “Conta desabilitada. Contate o responsável.” |
Além disso, o parâmetro WarnDaysToExpire retorna quantos dias faltam para a senha expirar, permitindo um aviso antecipado (“sua senha expira em N dias”).
4. Como fazer: tela de login personalizada
- Crie uma Tela de login com dois campos — usuário e senha (o campo de senha com o texto ocultado) — e um botão Entrar.
- No evento Click do botão, chame
LoginUsercom os valores digitados e leia oOpStatus:
' Click do botao "Entrar" — usuario/senha vem dos campos da tela (nunca fixos no script)
Sub BtnEntrar_Click()
Dim ok, op, aviso, usr, pwd
' Campo em branco devolve Null; passar Null ao LoginUser gera erro 0x80004003
' (ponteiro invalido). Concatenar com "" converte Null/Empty em string vazia.
usr = Trim("" & txtUsuario.Value)
pwd = "" & txtSenha.Value
If usr = "" Or pwd = "" Then
MsgBox "Informe o usuário e a senha.", vbExclamation
Exit Sub
End If
ok = Application.LoginUser(usr, pwd, op, aviso)
If ok Then
If op = 4 Then
MsgBox "Login efetuado. É obrigatório trocar a senha.", vbExclamation
Application.ChangePassword ' abre o diálogo de troca de senha
ElseIf IsNumeric(aviso) And aviso >= 0 And aviso <= 5 Then
MsgBox "Atenção: sua senha expira em " & aviso & " dia(s).", vbInformation
End If
' ... segue para a Tela principal da aplicação ...
Else
Select Case op
Case 2: MsgBox "Usuário ou senha inválidos.", vbExclamation
Case 8: MsgBox "Sua senha expirou. Contate o responsável pela aplicação.", vbExclamation
Case 16: MsgBox "Conta bloqueada por excesso de tentativas. Contate o responsável.", vbCritical
Case 32: MsgBox "Conta desabilitada. Contate o responsável pela aplicação.", vbCritical
Case Else: MsgBox "Falha no login (status " & op & ").", vbExclamation
End Select
End If
End Sub
Pontos de atenção do método:
- Valide os campos antes de chamar. Um campo de texto em branco devolve
Null, e passarNullaoLoginUsergera o erro de script0x80004003(ponteiro inválido) — uma caixa de erro do Viewer que oOpStatusnão chega a tratar. Converta com"" & campo.Valuee recuse usuário ou senha em branco antes da chamada. LoginUser(Usuario, Senha, OpStatus, WarnDaysToExpire)retorna Booleano (sucesso/falha); o status detalhado vem emOpStatus. Uma credencial errada não gera erro de script (Errpermanece0) — o resultado está no Booleano e noOpStatus.- O nome de usuário não diferencia maiúsculas/minúsculas; a senha diferencia.
- Para usuários do tipo Windows (Active Directory), a partir da 5.1 use
LoginWindowsUser(Usuario, Senha, OpStatus)— a leitura doOpStatusé a mesma.
5. Observações e boas práticas
- Bloqueio por tentativas. A propriedade
LoginRetriesdefine quantas tentativas são permitidas antes do bloqueio; alinhe a mensagem de "conta bloqueada" (OpStatus16) a esse limite. - Alternativa nativa. Quando não for preciso personalizar as mensagens,
Application.Login(True)abre o diálogo padrão do E3 (o usuário digita as credenciais) e mostra a confirmação/falha. - Mantenha o usuário logado visÃvel. Os eventos
OnLogin/OnLogoutdo Viewer permitem atualizar um display do usuário atual quando o login muda.
Artigos relacionados
- Forçar troca de senha no primeiro login com o método LoginUser. - Elipse Knowledgebase
- Aplicação exemplo: Personalizando a tela de login no E3. - Elipse Knowledgebase
- Como alterar a senha de um usuário em tempo de execução.
