Chamar APIs do Windows

Discussão sobre a Xailer

Moderador: Moderadores

Avatar do usuário
André Corrêa
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 03 Nov 2015 07:46
Localização: Caraguatatuba/SP

Chamar APIs do Windows

Mensagem por André Corrêa »

Bom dia,

Pesquisei bastante sobre o assunto antes de abrir um novo tópico, mas não encontrei a informação que queria.
Já fiz uso de algumas funções da API do Windows em Delphi para manipular as letras de unidade atribuídas aos discos.
Tenho um aplicativo em Delphi que permite listar e alterar a letra atribuída a um pendrive, por exemplo.
As funções chamadas são "GetVolumeNameForVolumeMountPoint()", "DeleteVolumeMountPoint", "SetVolumeMountPoint()"
e "GetDriveType()".
A questão é que não estou conseguindo chamar essas funções pelo Xailer. Encontrei apenas uma substituta para "GetDriveType",
que seria a "GetDrives()".
Alguém sabe como devo fazer para chamar essas funções? Já tentei colocar todos os headers referentes ao Windows na cláusula
#include, mas a IDE não reconhece as funções.

Obrigado,

André Luiz
-- André Corrêa

"Opte por aquilo que faz o seu coração vibrar, apesar de todas as consequências". - Osho
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Chamar APIs do Windows

Mensagem por fladimir »

Se vc tiver elas em C dá pra usar agora se entendi bem chamar as q tem no Delphi talvez através de Dll.

Vou ver aki se acho algo relativo a essas funções e te falo.
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
André Corrêa
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 03 Nov 2015 07:46
Localização: Caraguatatuba/SP

Chamar APIs do Windows

Mensagem por André Corrêa »

fladimir,

Essas APIs podem ser consultadas aqui https://msdn.microsoft.com/en-us/librar ... s.85).aspx.
Eu achava que elas poderiam ser invocadas a partir de qualquer linguagem ou IDE sem muito esforço, já que fazem parte do sistema
operacional, mas parece que não é bem assim.
Também não encontrei nenhuma Classe, nem função no Xailer que permita manipular as letras das unidades dessa forma.
Se souber de alguma, me avise, por favor.


Obrigado.
-- André Corrêa

"Opte por aquilo que faz o seu coração vibrar, apesar de todas as consequências". - Osho
sambomb
Usuário Nível 3
Usuário Nível 3
Mensagens: 250
Registrado em: 24 Out 2008 17:02
Localização: Itaocara - RJ - Brasil

Chamar APIs do Windows

Mensagem por sambomb »

Código: Selecionar todos


Procedure Teste()

   ?GetLogicalDrives()

Return


  DLL32 function GetLogicalDrives();
        AS BOOL PASCAL FROM 'GetLogicalDrives';
        LIB 'kernel32.dll'

Testa assim e vê se vai funcionar
Imagem

Rca Sistemas - Itaocara - RJ
Avatar do usuário
André Corrêa
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 03 Nov 2015 07:46
Localização: Caraguatatuba/SP

Chamar APIs do Windows

Mensagem por André Corrêa »

sambomb,

Fiz o teste, mas acusa "Syntax error "syntax error at 'FUNCTION'" na linha LIB "kernel32.dll".
Vou tentar outros meios. Na verdade, o que queria fazer é simples. Quero alterar a letra de
unidade atribuída pelo Windows a um pendrive, mas sem a necessidade de acessar o gerenciador
de disco. Vou ver se consigo chamar o DISKPART e fazer a alteração via programação.

Obrigado.
-- André Corrêa

"Opte por aquilo que faz o seu coração vibrar, apesar de todas as consequências". - Osho
sambomb
Usuário Nível 3
Usuário Nível 3
Mensagens: 250
Registrado em: 24 Out 2008 17:02
Localização: Itaocara - RJ - Brasil

Chamar APIs do Windows

Mensagem por sambomb »

Pode ser por eu usar Fivewin, verifica comandos semelhantes ae de chamada a DLL
Imagem

Rca Sistemas - Itaocara - RJ
Avatar do usuário
André Corrêa
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 03 Nov 2015 07:46
Localização: Caraguatatuba/SP

Chamar APIs do Windows

Mensagem por André Corrêa »

Bom dia,

Obrigado sambomb, mas descobri que só vai funcionar no Xailer se fizer um wrapper em C destas funções.
Postei a dúvida no fórum do Xailer e o desenvolvedor me enviou uma função que é justamente esse wrapper.
Antes deles responderem, consegui fazer o que queria, mas utilizando o DISKPART em segundo plano e gerando
um script em tempo de execução.

Seguem as funções:

Código: Selecionar todos

Procedure CriaScript(cDrive, cLetra)  //Cria um script que será lido pelo DISKPART

  Local Arq

  IF !File("C:\bat\DskScript.tmp")  //Checa se o arquivo existe e o cria, sempre vazio
    Arq:=FCreate("C:\bat\DskScript.tmp")
    FClose(Arq)
  ENDIF

  Arq:=FOpen("c:\bat\DskScript.tmp", 2)
  FWRITE(Arq, "SELECT VOLUME "+cDrive+CRLF+"ASSIGN LETTER="+cLetra) //Grava o script com as opções recebidas
  FCLOSE(Arq)

Return

Código: Selecionar todos

Procedure AlteraLetra()  //Altera a letra do disco removível utilizando o script gerado

  Local oErr

  TRY
    ShellExecute(,"OPEN","DISKPART","/s c:\bat\DskScript.tmp",,0) //Executa o DISKPART passando o script como parâmetro
    MsgAlert("Alteração efetuada com sucesso!")
  CATCH oErr
    MsgAlert("Não foi possível efetuar a alteração!")
    MsgAlert("Erro: " +oErr)
  END  

Return

Código: Selecionar todos

Function ListaLetras()  //Lista apenas as letras disponíveis

  Local aAlf:={"A:","B:","C:","D:","E:","F:","G:","H:","I:","J:","K:","L:",;
  "M:","N:","O:","P:","Q:","R:","S:","T:","U:","V:","W:","X:","Y:","Z:"}
  Local a01:=GetDrives() //Lista todos os drives para gerar a lista de letras disponíveis
  Local i
  Local nPos
    
  For i:=1 to Len(a01)
    nPos:=AScan(aAlf, a01[i])
    ADel(aAlf, nPos)
  Next

Return aAlf //Retorna apenas as letras disponíveis
-- André Corrêa

"Opte por aquilo que faz o seu coração vibrar, apesar de todas as consequências". - Osho
Avatar do usuário
André Corrêa
Usuário Nível 2
Usuário Nível 2
Mensagens: 81
Registrado em: 03 Nov 2015 07:46
Localização: Caraguatatuba/SP

Chamar APIs do Windows

Mensagem por André Corrêa »

Depois de algum tempo, baseado em códigos que encontrei na internet, consegui desenvolver 2 funções para controlar o serial e a letra de unidade
dos pendrives. Dessa forma é possível contornar o problema do sistema operacional alterar a letra de unidade.
Ao invés de se basear apenas nela para executar alguma rotina no sistema, pode-se utilizar também o serial, que é único e por meio dele,
alterar a letra de unidade em tempo de execução, sem o risco de selecionar o disco errado.

Seguem os códigos de ambas as funções, espero que possa ajudar alguém.

Obter o serial da letra informada:

Código: Selecionar todos

FUNCTION GetUsbSerial( f1 ) //Retorna o serial da letra informada
//f1 = Letra

LOCAL cDiskNum := "", cRet
LOCAL oDiskDrive, oWMIObjA, oWMIServerA, oWMIDiskDrive,;
oWMIObjA2,oWMIServerA2,oWMILogicalDisk, oLogicalDrive

  TRY
    oWMIObjA := GetActiveObject( "wbemScripting.SwbemLocator" )
  CATCH
    TRY
      oWMIObjA := CreateObject( "wbemScripting.SwbemLocator" )
    CATCH
      MsgAlert( "ERRO ! Nao criou objeto wbemScripting")
    return 0
    END
  END
  oWMIServerA := oWMIObjA:ConnectServer()
  oWMIDiskDrive := oWMIServerA:ExecQuery( "SELECT * FROM Win32_DiskDrive" )

  TRY
   oWMIObjA2 := GetActiveObject( "wbemScripting.SwbemLocator" )
  CATCH
    TRY
      oWMIObjA2 := CreateObject( "wbemScripting.SwbemLocator" )
    CATCH
      MsgAlert( "ERRO ! Nao criou objeto wbemScripting")
    return 0
    END
  END
  oWMIServerA2  := oWMIObjA2:ConnectServer()
  oWMILogicalDisk := oWMIServerA2:ExecQuery( "SELECT * FROM Win32_LogicalDiskToPartition" )

  FOR EACH oLogicalDrive IN oWMILogicalDisk
    IF SubStr(oLogicalDrive:Dependent, AT('"',oLogicalDrive:Dependent )+1,2 ) == f1
      cDiskNum := SubStr(oLogicalDrive:Antecedent, AT('#',oLogicalDrive:Antecedent )+1,1 )
    ENDIF
  NEXT

  FOR EACH oDiskDrive IN oWMIDiskDrive
    IF oDiskDrive:Name == "\\.\PHYSICALDRIVE" + cDiskNum .AND. oDiskDrive:InterfaceType == "USB"
      cRet := oDiskDrive:SerialNumber
    ENDIF
  NEXT

RETURN cRet
Obter a letra do serial informado:

Código: Selecionar todos

FUNCTION GetUsbLetter( f1 ) //Retorna a letra do serial informado
//f1 = Serial

LOCAL cDiskNum := "", cRet
LOCAL oDiskDrive, oWMIObjA, oWMIServerA, oWMIDiskDrive,;
oWMIObjA2,oWMIServerA2,oWMILogicalDisk, oLogicalDrive

  TRY
    oWMIObjA := GetActiveObject( "wbemScripting.SwbemLocator" )
  CATCH
    TRY
      oWMIObjA := CreateObject( "wbemScripting.SwbemLocator" )
    CATCH
      MsgAlert( "ERRO ! Nao criou objeto wbemScripting")
    return 0
    END
  END
  oWMIServerA := oWMIObjA:ConnectServer()
  oWMIDiskDrive := oWMIServerA:ExecQuery( "SELECT * FROM Win32_DiskDrive" )

  TRY
   oWMIObjA2 := GetActiveObject( "wbemScripting.SwbemLocator" )
  CATCH
    TRY
      oWMIObjA2 := CreateObject( "wbemScripting.SwbemLocator" )
    CATCH
      MsgAlert( "ERRO ! Nao criou objeto wbemScripting")
    return 0
    END
  END
  oWMIServerA2  := oWMIObjA2:ConnectServer()
  oWMILogicalDisk := oWMIServerA2:ExecQuery( "SELECT * FROM Win32_LogicalDiskToPartition" )

  FOR EACH oLogicalDrive IN oWMILogicalDisk
    FOR EACH oDiskDrive IN oWMIDiskDrive
      IF oDiskDrive:SerialNumber == AllTrim(StrTran(f1," ",""))
        cRet:= SubStr(oLogicalDrive:Dependent, AT('"',oLogicalDrive:Dependent )+1,2 )
      ENDIF
    NEXT
  NEXT

RETURN cRet
-- André Corrêa

"Opte por aquilo que faz o seu coração vibrar, apesar de todas as consequências". - Osho
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Chamar APIs do Windows

Mensagem por fladimir »

Obrigado por compartilhar André
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Chamar APIs do Windows

Mensagem por JoséQuintas »

Só pra complementar:
Pra usar API do Windows, eu uso um esquema do Harbour que acho prático.

Exemplo:

https://msdn.microsoft.com/pt-br/librar ... s.85).aspx

Descrição lá na Microsoft, indicando que está em Kernel32.dll:
BOOL WINAPI GetComputerName(
_Out_ LPTSTR lpBuffer,
_Inout_ LPDWORD lpnSize
);

Equivalente:

Código: Selecionar todos

#define KERNEL32DLL       "kernel32.dll"

FUNCTION mywin_GetComputerName()

   LOCAL cComputerName := Space(255), nSize := 250

   CallDll( "GetComputerNameA", KERNEL32DLL, @cComputerName, @nSize )
   RETURN cComputerName
Nome da função, aonde está, e os parâmetros. Praticamente igual ao manual da Microsoft.
A exceção, nesta função que peguei como exemplo, é a variável por referência (ponteiro), que precisa ter um tamanho que consiga armazenar o retorno.

Nota: GetComputerNameA, pra usar a versão em Ascii.
adicionar hbmisc.hbc na compilação, e no Harbour 3.2 é CallDll32()

nota2: essas coisas que mencionei tem lá no site:
lpBuffer (out)
A pointer to a buffer that receives the computer name or the cluster virtual server name. The buffer size should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters.
...
GetComputerNameW (Unicode) and GetComputerNameA (ANSI)
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Chamar APIs do Windows

Mensagem por rochinha »

Amiguinhos,

Ferramenta util para obter as funções e parâmetros das DLLs do Windows.

download
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder