Ir para conteúdo


Manimal

Cadastrado: 06 Jun 2012
Offline Última atividade: Ago 18 2017 06:02
-----

Tópicos que criei

Enorme coleção de e-books da Microsoft (GRÁTIS)

17 julho 2017 - 11:20

Pessoal, segue link para um blog de um camarada que oferece um montão de e-books sobre vários assuntos, todos da Microsoft.

 

Tem muita coisa boa, gratuita e extremamente relevante, só que tem que saber inglês.

 

Aliás saber inglês é OBRIGATÓRIO na nossa área. Não tem desculpas para não ter aprendido ainda.

 

Se vc é um daqueles que ainda não sabe inglês use o DUOLINGO para aprender. Alguns minutos por dia não matam ninguém!

 

Vamos ao link: https://blogs.msdn.m...e-2013-sharepo/


Systray

12 junho 2017 - 03:03

Olá galera.

 

Estou com uma situação irritante.

 

Tenho um programa que monitora certas máquinas para saber se estão ativas ou não (meus clientes).

 

Neste programa, quando eu clico com o BOTÃO ESQUERDO no ícone do Systray, ele abre o painel principal do programa.

 

Quando eu clico com o BOTÃO DIREITO no ícone do Systray, ele me mostra o menu com algumas opções. Uma dessas opções é a de ATUALIZAR (ou verificar novamente as máquinas).

 

Até aqui tudo bem!

 

Meu stress começou quando decidi que seria mais interessante adicionar a opção de CLIQUE DUPLO para ativar a ATUALIZAÇÃO (como se fosse um atalho).

 

Porém o AutoIt não permite o reconhecimento separado dos eventos do clique simples e do clique duplo!

 

Ou seja, é possível programar os dois eventos, mas ANTES do clique duplo, ele sempre reconhece o clique simples.

 

Para entender melhor usem o seguinte exemplo:

  1.  
  2. Opt("TrayAutoPause", 0)
  3. Opt("TrayOnEventMode", 1)
  4. Opt("TrayMenuMode", 1 + 2)
  5.  
  6. #include <TrayConstants.au3>
  7.  
  8. TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "SIMPLES")
  9. TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "DUPLO")
  10. TraySetOnEvent($TRAY_EVENT_SECONDARYUP, "SAIDA") ; clique com o botão direito no systray para sair
  11.  

Alguém tem alguma idéia?

A ordem dos comandos não influencia as funções nem os cliques...


Nome Completo dos Arquivos

07 março 2017 - 03:07

Olá pessoal.
 
Em uma dúvida recente aqui no fórum, um bug foi resolvido (ou criado) porque não foi informado o nome completo do arquivo.
Nestes anos de programação, vi muitos erros neste sentido ao trabalhar com arquivos, tantos erros meus como de tereceiros.
Então por padrão, decidi há muito tempo atrás, padronizar meus programas sempre com o nome completo dos arquivos, até para evitar dores de cabeça de graça.
 
Porém percebi que muitos não sabem o que é nome completo do arquivo e que esta não é uma dúvida de AutoIt, mas de operação de computadores de um modo geral.
Assim em qualquer função onde é informado um nome de arquivo, devemos ter o cuidado de sempre informar o nome completo, ou se não o fizermos, sabermos exatamente o que estamos omitindo e porquê.
 
Todo arquivo tem seu NOME COMPLETO dividido em 4 (quatro) partes. Essas partes são:
  1. LOCAL = em qual unidade ou lugar da rede que está localizado o arquivo
  2. CAMINHO = qual a estrutura de pastas e subpastas onde está localizado o arquivo
  3. NOME = nome efetivo do arquivo
  4. EXTENSÃO = sufixo que identifica o tipo do arquivo (úti para algumas funções do SO = Sistema Operacional)
 
Não se enganem, TODOS os arquivo seguem esta terminologia, em qualquer linguagem ou sistema seja Windows, Linux ou qualquer outro.
Destas 4 partes podemos "esquecer" ou "deixar de informar" até 2 partes:
  • LOCAL e/ou CAMINHO
Mas se não informamos, o SO vai "preencher" estas informações porque ele SEMPRE necessita das 4 partes (NOME COMPLETO).
E talvez esse preenchimento não seja o mais adequado as nossas necessidades do programa naquele momento dando margem a erros e bugs inexplicáveis!
 
Vou explicar melhor através de exemplos:
 
  1.  
  2. C:\ARQUIVO.TXT
  3.    LOCAL = C:
  4.    CAMINHO = \
  5.    NOME = ARQUIVO
  6.    EXTENSÃO = .TXT
  7.  
  1.  
  2. D:\MEU DOCS\DOWNLOADS\FILMES.XML
  3.    LOCAL = D:
  4.    CAMINHO = \MEU DOCS\DOWNLOADS\
  5.    NOME = FILMES
  6.    EXTENSÃO = .XML
  7.  
  1.  
  2. \\192.168.1.11\USERS\FULANO\DESKTOP\LIVRO.PDF
  3.    LOCAL = \\192.168.1.11
  4.    CAMINHO = \USERS\FULANO\DESKTOP\
  5.    NOME = LIVRO
  6.    EXTENSÃO = .PDF
  7.  
E assim por diante. Não é difícil e normalmente fazemos isso (NOME COMPLETO) sem perceber.
Porém ao programarmos, temos o hábito de esquecer destas 4 partes e colocamos apenas:
 
  1.  
  2. Arquivo = "PROGRAMA.EXE"
  3.  ou 
  4. FileRead("NOMES.TXT")
  5.  ou
  6. IniRead("CONFIG.INI", ...)
  7.  
Quando deixamos de informar o nome completo, o SO precisa completar todos os campos para poder processar o arquivo.
Nos casos acima, onde foi informado apenas as partes 3 e 4 de cada nome, as partes 1 e 2 serão preenchidas com o padrão do SO naquele momento.
Assim, internamente a função FileRead vai assumir a unidade e pasta atual do programa para completar as informações necessárias.
 
Isso é muito bom e funciona certinho quando clicamos 2x no arquivo dentro de uma pasta por exemplo.
Mas e se chamamos o programam (script) através de um arquivo BAT (ou CMD). E se executarmos nosso script a partir do comando EXECUTAR do Windows.
De qual pasta ele irá completar as partes faltantes?
 
Por isso recomendo que em todas as operações de arquivo, tenhamos por hábito informar TODAS as partes do nome dos arquivo que trabalhamos.
 
  1.  
  2. $Arquivo = @ScriptDir & "\PROGRAMA.EXE"
  3.  ou 
  4. FileRead("C:\PASTA\NOMES.TXT")
  5.  ou
  6. IniRead("D:\MEUPROG\CONFIG.INI", ...)
  7.  
São pequenas alterações que resolvem grandes problemas.
 
Aproveitem e usem as macros do AutoIt que dizem que pasta estamos
  • @ScriptDir
  • @ScriptName
  • @ScriptFullPath
como base para o nome dos seus arquivos.
 
Também é perfeitamente possível o uso das referências relativas como "..\" ou ".\", mas devem ser muito bem trabalhadas, com bastante atenção.
As operações com arquivos que mais incomodam são as de copiar, renomear ou apagar arquivos. As que mudam alguma característica como data e/ou hora também são exigentes.
 
#FikaDika  ;)

Atributos de Segurança

24 agosto 2016 - 09:10

Bom dia galera.

 

É o seguinte: Estou precisando fazer um sistema de comunicação entre aplicações, conhecido como IPC (Inter Process Communication).

 

Dentre os vários métodos disponíveis, selecionei o MailSlot para utilizar. Outra opção interessante seria o NamedPipes (como 2a opção).

 

Procurando, encontrei esta UDF da Trancexx: https://www.autoitsc...06710-mailslot/

 

Inclusive em vário posts do fórum americano, encontrei o JScript (fundador do nosso fórum brasileiro) trabalhando nesta linha do IPC. Mas parece que o JScript está meio fora de comunicação, aliás seria bom poder falar com ele pois acredito que ele já tenha passado pelo mesmo problema e já deve ter achado a solução, mas...

 

A UDF desenvolvida pela Trancexx é excelente, simples e funcional, porém peca no que se refere a questão segurança, pois usuários diferentes com acessos limitados não conseguem compartilhar essa comunicação.

 

Se executada na mesmo usuário, funciona muito bem, mas tipo entre um administrador e um usuário normal, não funciona. Fui atrás e descobri que é por causa da permissão de acesso (ou gravação).

 

No post da UDF, na segunda página, tem outro colega com o mesmo problema e que resolveu, inclusive explicando como fez e até passando o script.

 

Infelizmente não consegui fazer funcionar a contento, ou seja, por causa das limitações de segurança, a comunicação não acontece.

 

Talvez eu já esteja cego de tanto olhar e testar e o erro está PULANDO na minha frente, mas não consegui achar o problema. Até consegui fazer duas versões diferentes que teoricamente deveriam funcionar, porém nenhuma funciona!

 

O problema está ocorrendo quando na criação do canal de comunicação, onde deveria ser setado a segurança, não o é! Assim tentei modificar a função de acordo com as sugestões encontradas mas não obtive sucesso.

 

Segue alguns links para acesso e dúvidas sobre as funções envolvidas:

 

A UDF original está no link do MailSlot, inclusive tem exemplos.

Estrutura do SECURITY_ATTRIBUTES = https://msdn.microso...0(v=vs.85).aspx

CreateMailslot  = https://msdn.microso...7(v=vs.85).aspx

InitializeSecurityDescriptor = https://msdn.microso...3(v=vs.85).aspx

SetSecurityDescriptorDacl = https://msdn.microso...3(v=vs.85).aspx

 

Finalmente, adaptei esta função para que retornasse uma permissão para todos poderem ler e gravar neste canal de comunicação (MailSlot):

A função abaixo está trabalhando diretamente na estrutura de dados, diferente da sintaxe original exigida pelas funções:

  1.  
  2. Func _SetNONESecurity()
  3. Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
  4. If @error Then Return SetError(@error, @extended, -1)
  5. ; Initialize the security descriptor.
  6. Local Const $SECURITY_DESCRIPTOR_REVISION = 1
  7. Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", "struct*", $tSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
  8. If @error or not $aRet[0] Then Return SetError(@error, @extended, -1)
  9. ; Add the NULL DACL specifying access to everybody.
  10. $aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", "struct*", $tSecurityDescriptor, "bool", 1, "ptr", Null, "bool", 0)
  11. If @error or not $aRet[0] Then Return SetError(@error, @extended, -1)
  12. ; Create a SECURITY_ATTRIBUTES structure.
  13. $tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
  14. ; Assign the members.
  15. DllStructSetData($tSecurityAttributes, "Length", DllStructGetSize($tSecurityAttributes))
  16. DllStructSetData($tSecurityAttributes, "Descriptor", DllStructGetPtr($tSecurityDescriptor))
  17. DllStructSetData($tSecurityAttributes, "InheritHandle", False)
  18. Return DllStructGetPtr($tSecurityAttributes)
  19. EndFunc ;==>_SetNULLSecurity
  20.  
  21.  

Esta segunda função, praticamente igual só modificando para ficar de acordo com a sintaxe exigida pelas funções:

  1.  
  2. Func _SetNONESecurity()
  3. Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
  4. If @error Then Return SetError(@error, @extended, -1)
  5. ; Initialize the security descriptor
  6. Local Const $SECURITY_DESCRIPTOR_REVISION = 1
  7. Local $pSecurityDescriptor = DllStructGetPtr($tSecurityDescriptor)
  8. Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", "ptr", $pSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
  9. If @error or not $aRet[0] Then Return SetError(@error, @extended, -1)
  10. ; Add the NULL DACL specifying access to everybody
  11. $aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", "ptr", $pSecurityDescriptor, "bool", True, "ptr", Null, "bool", False)
  12. If @error or not $aRet[0] Then Return SetError(@error, @extended, -1)
  13. ; Create a SECURITY_ATTRIBUTES structure
  14. Local $tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
  15. If @error Then Return SetError(@error, @extended, -1)
  16. ; Assign the members
  17. DllStructSetData($tSecurityAttributes, "Length", DllStructGetSize($tSecurityAttributes))
  18. DllStructSetData($tSecurityAttributes, "Descriptor", DllStructGetPtr($tSecurityDescriptor))
  19. DllStructSetData($tSecurityAttributes, "InheritHandle", False)
  20. Return DllStructGetPtr($tSecurityAttributes)
  21. EndFunc ;==>_SetNONESecurity
  22.  
  23.  

Se alguém puder dar uma olhada, agradeço.

Obrigado.