Página 1 de 1

Acesso dbfs em pastas SpecialFolders

Enviado: 08 Fev 2013 14:48
por Pablo César
SpecialFolder a que me refiro são as pastas como C:\Documents and Settings\Pablo César\Meus documentos etc.

No Stru quero adicionar mais uma opção. Que funcione o ContextMenu no Explorer. Isto é, apontando e clicando com o botão direito do mouse sobre um arquivo dbf, possa dar mais uma opção: Stru - Listar. Então o usuário pode listar a estrutura do dbf de dentro do Explorer.

Mas hoje percebi algo muito estranho, se eu possuo um arquivo dbf no SpecialFolder, ele não abre e dá erro, abortando o programa. Então comecei fazer uma série de testes para contornar esse problema. Não sei ainda se é por ser XP e não é por falta de direitos como administrador. Então passo a seguir as tentativas e suponhamos que cPath:="C:\Documents and Settings\Pablo César\Meus documentos\" :

1. Coloquei If !File(cPath+cDbf) e mesmo sabendo que o arquivo dbf está lá, ele retorna como não existente.
2.
O engraçado, acho que isto é tema de hackers... hihi, ele aceita o cPath como "C:\DOCUME~1\PABLOC~1\MEUSDO~1", isto é nomes curtos no padrão 8x3. Daí abre/lê normalmente. Também o STRU funciona na linha de comando já posicionado na pasta C:\Documents and Settings\Pablo César\Meus documentos.
3. Tentei obter o ShortPathName e me retorna vazio. Isto é, o sistema não consegue enxergar a pasta que neste caso é um SpecialFolder.
4. Também tentei posicionar-me dentro da pasta na execução do programa. Mas nada.
5. Nem o IsDirectory() funciona, que sempre funcionou bem.

Alguém já passou por isto. Do que eu lembro, já aconteceu com muitos, mas era Clipper. E eu em Clipper sempre coloquei o caminho em modo curto e funcionou sempre mesmo nas SpecialFolders. E agora que o usuário pode selecionar o arquivo mediante o GetFile, se ele selecionar um dbf que está dentro do Meus Documentos não vai funcionar. E não creio que eu consiga copiar esse dbf em outra pasta, pois não é exergado.

Alguém pode me dar uma luz ?

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 02:37
por rochinha
Amiguinho,

Quanto a colocar uma opção no menu de contexto use minha dica, lembrando que o stru.exe deve estar dentro da pasta %windir%\system32

Código: Selecionar todos

Windows Registry Editor Version 5.00

;================================================
; \\\\\\\\\\\\\\   Context Menus   //////////////
;================================================
;------------------------------------------------------------------------------------------------------------
[HKEY_CLASSES_ROOT\.dbf]
"Content Type"="Text"
@="dbffile"

[HKEY_CLASSES_ROOT\dbffile]
@="Application Extension"

[HKEY_CLASSES_ROOT\dbffile\Shell\Estrutura\command]
@="Stru.EXE \"%1\""
Execute e confirme.

Quanto a nomes extensos, se voce não tiver uma função ai posso ver uma que uso.

Para chegar a pasta Meus Documentos, pegue a variável ambiental %HOMEPATH% e adicione \Meus Documentos. HOMEPATH traz o caminho da pasta Meus Documentos do usuário ativo.

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 08:46
por Pablo César
Olá Rochinha, obrigado pela sua instrução do Context Menu, gostei. Vou ainda avaliar outras opções e darei um retorno.
Para chegar a pasta Meus Documentos, pegue a variável ambiental %HOMEPATH% e adicione \Meus Documentos. HOMEPATH traz o caminho da pasta Meus Documentos do usuário ativo.
Sim tem essa forma também quando for versão do Windows XP pra cima. Aprecio a sua dica, mas tem várias formas de obter o caminho do "Meus documentos". A questão é outra Rochinha. Não sei se você já viu o meu aplicativo STRU.exe, vou tentar exemplificar para que você entenda o meu caso. O STRU entre outras funções, lista a estrutura dos dbfs e como disse queria implementar a opção de Context Menu. Mas suponhamos que o usuário tenha um dbf nessa pasta "Meu documentos" e clique com o botão direito e execute o STRU. Até ai tudo bem, mas de dentro do programa ele não dá acesso a esse dbf. Isto é, para o aplicativo, ele não existe, não dá para abrir e nem dá para obter (com aquela função de conversão) o nome curto sequer. Isso porque é um SpecialFolders. Faça um teste ai, coloque um dbf no meus documentos e tente abrir com o path completo e o executável fora da pasta "meus documentos". Você vai ter o mesmo caso meu. Agora se você passar o path completo mas em forma de nome-curto, ai funciona. Estou frustrado com isso :( Mas pode ser que haja uma função em C que possa interagir com essa SpecialFolder e obter o nome curto através do nome longo. Assim espero.
Quanto a nomes extensos, se voce não tiver uma função ai posso ver uma que uso.
Quanto a isso não há problemas. O próprio HMG possui a função de converter de nomes longos a curtos. Mas como disse o problema é outro.

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 09:34
por rochinha
Amiguinho,

O que voce precisa é descobrir qual o caminho real da pasta virtual, ou seja, o SpecialFolder: Meus Documentos refere-se a qual pasta real?

A partir dela voce usa uma função de encurtamento.

Código: Selecionar todos

Function GetSpecialFolders( cSpecialFolder )
   oSpecialFolderPath := CreateObject( "Wscript.Shell" )
   return oSpecialFolderPath:SpecialFolders( cSpecialFolder )
Uso:

Código: Selecionar todos

...
? LFN2SFN( GetSpecialFolders( "Meus Documentos" ) )
...
LFN2SFN() - Função que transforma nomes longos em curtos.

Código: Selecionar todos

Function Lfn2Sfn( cDir )
   local cBuffer := space(261)
   local nLen
   nLen := GetShortPathName( cDir, @cBuffer, len(cBuffer) )
   return left( cBuffer, nLen )

DLL32 Function GetShortPathName( lpLongPath AS LPSTR,;
                                                      lpShortPath AS LPSTR,;
                                                      wBufferLen AS DWORD ) AS DWORD ;
                                                     PASCAL FROM "GetShortPathNameA" LIB "kernel32.dll"

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 09:53
por rochinha
Amiguinho,

Quanto a conhecer seu aplicativo, digo que sim, inclusive esta dentro de minha pasta UTILS acima da WAPI.

Teste:

Código: Selecionar todos

                ? "Desktop: " + GetSpecialFolders("Desktop") , + ;
                  "MyDocuments: " + GetSpecialFolders("MyDocuments") , + ;
                  "Startmenu: " + GetSpecialFolders("startmenu") , + ;
                  "AllUsersDesktop: " + GetSpecialFolders("AllUsersDesktop") , + ;
                  "AllUsersStartMenu: " + GetSpecialFolders("AllUsersStartMenu") , + ;
                  "AllUsersPrograms: " + GetSpecialFolders("AllUsersPrograms") , + ;
                  "AllUsersStartup: " + GetSpecialFolders("AllUsersStartup") , + ;
                  "Favorites: " + GetSpecialFolders("Favorites") , + ;
                  "Fonts:" + GetSpecialFolders("Fonts") , + ;
                  "NetHood: " + GetSpecialFolders("NetHood") , + ;
                  "PrintHood: " + GetSpecialFolders("PrintHood") , + ;
                  "Programs: " + GetSpecialFolders("Programs") , + ;
                  "Recent: " + GetSpecialFolders("Recent") , + ;
                  "SendTo: " + GetSpecialFolders("SendTo") , + ;
                  "Startup: " + GetSpecialFolders("Startup") , + ;
                  "Templates: " + GetSpecialFolders("Templates")	
Também:

Código: Selecionar todos

                ? "Windows: " + GetSpecialFolders(0) , + ;
                  "System32: " + GetSpecialFolders(1) , + ;
                  "Temp: " + GetSpecialFolders(2) 
Retorne, pois apenas implementei e não testei. Na verdade implementei aqui no forum para uso futuro.

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 10:34
por Pablo César
Quanto a conhecer seu aplicativo, digo que sim, inclusive esta dentro de minha pasta UTILS acima da WAPI.
Ahhh legal !

Rochinha, o GetSpecialFolders, eu já tenho e não vejo a utilidade no STRU. Ora porque, é o usuário que escolhe o arquivo que deseja listar. Portanto pode ser em vários lugarfes e eu quis dizer que quando o usuário escolhe um dbf que está no "Meus documentos" eu me referia ao path completo. Isso já traz com a função GetFile. Mas o path completo que traz é do tipo long name. Então, não vejo a necessidade de uso da função GetSpecialFolders. Estou errado ?

Quanto a sua função Lfn2Sfn, não sei se é a versão do Harbour ou se você esqueceu de listar o código em C. Mas a função GetShortPathName não está no Harbour nativamente. Sim achei o WAPI_GETSHORTPATHNAME (Changelog 2010-02-13 Przemyslaw Czerpak) e também não funcionou.

Peço a ti por gentileza, fazer um teste:

Código: Selecionar todos

Function Main
Local cPath_Long:=GetSpecialFolders(16) // que é a pasta Meus documentos no seu PC

cPath_Short := Lfn2Sfn( cPath_Long )

MsgInfo( cPath_Short )

Return Nil

Function Lfn2Sfn( cDir )
Local cBuffer := space(261)
Local nLen

nLen := GetShortPathName( cDir, @cBuffer, len(cBuffer) )
Return Left( cBuffer, nLen )
Mas este executável armazene ele em qualquer pasta menos na pasta "Meus documentos" do seu pc e me diga se trouxe o nome curto, por favor. Ahhh se puder anexar o executável na sua próxima mensagem, eu posso também testar aqui. Quero ver se tem jeito ou não.

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 11:04
por Pablo César
Epa !! Conseguí com esse mesmo código que passei !

Obrigado Rochinha, você é um anjo ! Valeu !

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 11:34
por rochinha
Amiguinho,

Obrigado. Somos pequenos pedaços de cérebro, funcionando e conseguindo o resultado para outros pedaços.

A função GetShortPathName() que passei foi um snippet de código, mas não sei se existe no Harbour. Preciso dar uma olhada no site de ajuda.

Acesso dbfs em pastas SpecialFolders

Enviado: 09 Fev 2013 16:04
por Pablo César
rochinha escreveu:Somos pequenos pedaços de cérebro, funcionando e conseguindo o resultado para outros pedaços.
Como diz Chico Buarque na sua letra: "Todos juntos somos fortes. Somos flecha e somos arco.". O melhor do fórum é poder compartilhar conhecimento. "Pois tudo que até hoje sabemos, é devido a varias pessoas que compartilharam e assim esperam que você faça o mesmo."

A função GetShortPathName() não existe em Harbour, a que assemleha-se é da hbwhat a função VWN_GETSHORTPATHNAME mas em 2009-07-11 a contrib foi removida por Viktor Szakats.

Num código fonte hbvpdft.prg tem o seguinte comentário:
This requires hbwhat, which in turns requires xhb.

Google translation: Isto requer hbwhat, que por sua vez requer XHB.
Então não consegui nem com GetShortPathName() nem com VWN_GETSHORTPATHNAME, consegui com WAPI_GETSHORTPATHNAME( cDir, @cBuffer, Len(cBuffer) ).

Mas ainda tenho algo estranho no STRU que não funciona normalmente como no exemplo citado. Vou ver o que é talvez com mais calma consiga descobrir o que eu fiz de errado.