_ddqs. 发表于 2010-10-28 19:44:28

利用DOS流取短名的函数(畸形名称也可以)(纯练手产物,结果14楼)[已解决]

本帖最后由 _ddqs. 于 2010-12-30 18:49 编辑

后期源码下载在 14 楼:http://www.autoitx.com/forum.php?mod=redirect&goto=findpost&ptid=19330&pid=231817&fromuid=7653769
------;XP-SP3测试(操作畸形不件夹)(查看——短文件名)(不使用缓冲文件识别,直接流操作)
#include <Constants.au3>
;#include<process.au3>

$_weizi = 'f:\'
$_weizi = 'f:\我的文档\'
;$_filename = '爱 什么 是什么........'
$_filename = ' 爱 什么 是什么........'
DirCreate($_weizi & $_filename & './')

$f=$_weizi&$_filename
;$f="C:\Program Files\yqsclient.bak"
;$f="C:\Program Files\yqsclient.bak\"
;$f="C:\Program Files\yqsclient\"
;$f="C:\Program Files\yqsclient"
$a = _FileGetShortName($f)
MsgBox(0,"<"&$f&">取得的短文件名为:",$a )


Func _FileGetShortName($FilePath)
       
        Local $fp=StringSplit($FilePath,"\"), $fpp
        If $fp<>"" then
                $fpp=""
                $c=UBound($fp)-1
        Else
                $fpp="\"
                $c=UBound($fp)-2
        EndIf
        Local $fps
        For $i=1 To $c
                If $fps<>"" Then$fps &= "\"
                $fps &= $fp[$i]
                If $i>1 Then $fps = _FileGetShortName_($fps)
        Next
       
        Return $fps&$fpp
EndFunc


Func _FileGetShortName_($FilePath)
       
        Local $fp=StringSplit($FilePath,"\")
        Local $fps
        For $i=1 To UBound($fp)-2
                $fps &= $fp[$i]&"\"
        Next
        Local $string='FOR /F "eol=; tokens=2,3* delims=>" %i in ('&"'dir/x/n "& $fps &' ^| find /i /n "'& $fp &'" '&"') do @ECHO %i"
        Local $foo = Run(@ComSpec & " /c "&$string, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        Local $line
        While 1
                $line &= StdoutRead($foo)
                If @error Then ExitLoop(StdioClose($foo))
        Wend
        $line = StringSplit ( $line, @CR, 0)
        For $i=1 To $line
                $ros = $line[$i]
;~#CS (先按位置取字串,比这更准确)(如果原名以空格开头的则有可能不准)
                $ros = StringReplace($ros,"          ","*")
                While 1
                        $ros = StringReplace($ros,"   ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"    ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"   ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros," ","*")
                                If @extended Then ExitLoop
                        If 1 Then ExitLoop
                WEnd
;                $ros = StringReplace($ros,"   ","*")
;                $ros = StringReplace($ros,"**","*")
                $ros = StringSplit ( $ros, "*", 0)
;~#CE
                If $ros = $fp Then ExitLoop;Return $ros
        Next
        Return $fps&$ros
EndFunc

_ddqs. 发表于 2010-10-28 19:55:30

InputBox("","<"&$f&">"&@CR&@CR&"取得的短文件名为:",$a)

kood481748 发表于 2010-10-28 20:52:21

这个东西别人早就研究出来了,你还去研究,这无疑是浪费时间,或者你根本就是拿别人的代码来改了就说自己原创

_ddqs. 发表于 2010-10-28 22:50:23

刚上路
别人的看不懂
准练练手

_ddqs. 发表于 2010-10-28 22:52:02

;XP-SP3测试(操作畸形不件夹)(查看——短文件名)(不使用缓冲文件识别,直接流操作)
#include <Constants.au3>
;#include<process.au3>

$_weizi = 'd:\'
$_weizi = 'd:\我的文档\'
$_weizi = 'd:\我的文档\我的文档.bak\'
$_filename = '爱 什么 是什么........'
;$_filename = ' 爱 什么 是什么........'
DirCreate($_weizi & $_filename & './')

$f=$_weizi&$_filename
;$f &= "\yqsclient.exe"
$f &= "\bargames.exe"
$f="d:\我的文档\爱什么~1\yqsclient.exe"

;$f="C:\Program Files\yqsclient.bak"
;$f="C:\Program Files\yqsclient.bak\"
;$f="C:\Program Files\yqsclient\"
;$f="C:\Program Files\yqsclient"
;$f="C:\Program Files\yqsclient.bacccc"
;$f="C:\Program Files\yqsclient.bacccc\"
;$f="C:\Program Files\yqsclient\yqsclient.exe"
;$f = 'd:\我的文档\RealVNC_454连接'
;$f = 'd:\我的文档\RealVNC_454连接\Documentation\VNC Enterprise Edition on the Web.url'



$a = _FileGetShortName($f)
;MsgBox(0,"<"&$f&">取得的短文件名为:",$a )
InputBox("","<"&$f&">"&@CR&@CR&"取得的短文件名为:",$a)


Func _FileGetShortName($FilePath)
       
        Local $fp=StringSplit($FilePath,"\"), $fpp,$ros
        If $fp<>"" then
                $fpp=""
                $c=UBound($fp)-1
        Else
                $fpp="\"
                $c=UBound($fp)-2
        EndIf
        Local $fps
        For $i=1 To $c
                If $fps<>"" Then$fps &= "\"
                $fps &= $fp[$i]
                If StringLen($fp[$i])<9 Then
                        ContinueLoop ;字符长度9个以内不处理,处理也是错误!
                Else
                        $ros = $fp[$i]
                        $ros = StringSplit($ros,".")
                        If StringLen($ros)<9 And StringLen($ros)<4 And $ros<3 Then ContinueLoop ;
                EndIf
                If $i>1 Then $fps = _FileGetShortName_($fps)
        Next
       
        Return $fps&$fpp
EndFunc


Func _FileGetShortName_($FilePath)
       
        Local $stra=FileGetAttrib ($FilePath)
        If StringInStr($stra,"D")=0And $stra<>"" Then;如果是,当成文件处理(有待恶补……再写写)
                ;$FilePath = _FileGetShortName_isFILE($FilePath)
                ;$FilePath = FileGetShortName ($FilePath)
                Return $FilePath
        EndIf
       
        Local $fp=StringSplit($FilePath,"\")
        Local $fps
        For $i=1 To UBound($fp)-2
                $fps &= $fp[$i]&"\"
        Next
        Local $string='FOR /F "eol=; tokens=2,3* delims=>" %i in ('&"'dir/x/n "& $fps &' ^| find /i /n "'& $fp &'" '&"') do @ECHO %i"
        Local $foo = Run(@ComSpec & " /c "&$string, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        Local $line
        While 1
                $line &= StdoutRead($foo)
                If @error Then ExitLoop(StdioClose($foo))
        Wend
        $line = StringSplit ( $line, @CR, 0)
        For $i=1 To $line
                $ros = $line[$i]
;~#CS (先按位置取字串,比这更准确)(如果原名以空格开头的则有可能不准)
                $ros = StringReplace($ros,"          ","*")
                While 1
                        $ros = StringReplace($ros,"   ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"    ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"   ","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros,"","*")
                                If @extended Then ExitLoop
                        $ros = StringReplace($ros," ","*")
                                If @extended Then ExitLoop
                        If 1 Then ExitLoop
                WEnd
;                $ros = StringReplace($ros,"   ","*")
;                $ros = StringReplace($ros,"**","*")
                $ros = StringSplit ( $ros, "*", 0)
;~#CE
                If $ros = $fp Then ExitLoop;Return $ros
        Next
        ;MsgBox(0,"",$fps&$ros)
        Return $fps&$ros
EndFunc

_ddqs. 发表于 2010-10-28 23:01:05

这个东西别人早就研究出来了,你还去研究,这无疑是浪费时间,或者你根本就是拿别人的代码来改了就说自己原 ...
kood481748 发表于 2010-10-28 20:52 http://www.autoitx.com/images/common/back.gif


    {:face (245):}
给俺个连接,俺去学习学习!
条条大道通罗马,何况自己写的东西还有多少个不同版本,并不是有了就不去做
去做了就想更有能合适自己的东西
同时也能加深自己的认识

kood481748 发表于 2010-10-28 23:51:51

你自己运用论坛的搜索功能找一下看看,反正我之前是见人做过这类似程序的了,
和别人做的东西对比一下,也互相学习一下。

_ddqs. 发表于 2010-10-29 00:40:27

本帖最后由 _ddqs. 于 2010-10-29 10:23 编辑


自己试下,对文件名或中文名称也能识别了!
代码不多贴,贴多了就乱

Func _FileGetShortName_isFILE($FilePath)
       
        Local $fp=StringSplit($FilePath,"\")
        Local $fps
        For $i=1 To UBound($fp)-2
                $fps &= $fp[$i]&"\"
        Next
        Local $string='FOR /F "eol=; tokens=2,3* delims=]" %i in ('&"'dir/x/n "& $fps &' ^| find /i /n "'& $fp &'" '&"') do @ECHO %i"
        Local $foo = Run(@ComSpec & " /c "&$string, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
        Local $line
        While 1
                $line &= StdoutRead($foo)
                If @error Then ExitLoop(StdioClose($foo))
        Wend
        $line = StringSplit ( $line, @CR, 0)
;        Local $ros1,$ros2
        For $i=1 To $line
                $ros = $line[$i]
                $ros = StringReplace($ros,1,"************************************")
                $ros = StringSplit ( $ros, $fp[$fp], 1) ;会区别大小写
                If @error<>1 Then
                        $ros = StringReplace($ros,"*"," ")
                        $ros = StringStripWS ( $ros , 8 )
                        ExitLoop
                EndIf
        Next
        If $ros="" Then Return "区别大小写,请指定正确名称。"
        Return $fps&$ros
EndFunc

_ddqs. 发表于 2010-10-29 00:47:58

你自己运用论坛的搜索功能找一下看看,反正我之前是见人做过这类似程序的了,
和别人做的东西对比一下,也 ...
kood481748 发表于 2010-10-28 23:51 http://www.autoitx.com/images/common/back.gif


是有看过
但试了不行(源码也没细看,看了头晕……功力不够)
并系统原有的函数也有时会出错
要不,就没动力自己去动手咯
玩也要有目的、有动力
没动力玩不了

C.L 发表于 2010-10-29 08:21:23

自已多写写代码,对自已的AU3水平的提高,确定有好处

_ddqs. 发表于 2010-10-30 08:35:25

写了就发,硬盘挂了,工作白忙
;X查看——短文件名(还是整合不了,加了2个自定义函数协助处理);类原有系统取短名函数功能!

#include <Constants.au3>


$f="f:\我的文档\『 提问交流 』 - AUTOIT CN AutoIt中文论坛acnau3软件汉化 - 分享您的技术!.url"
$f="f:\我的文档\『 提问交流 』 - AUTOIT CN AutoIt中文论坛acnau3软件汉化 - 分享您的技术!.URL"



$_FileGetShortName = _FileGetShortName($f)

If @error Then MsgBox(0,"出错啦!",@CR&"指定的名称错误或不存在."&@CR)
;;
$_FileGetShortName = InputBox("_FileGetShortName()","<"&$f&">"&@CR&@CR&"取得的短文件名为:",$_FileGetShortName)


Func _FileGetShortName($filename)
       
        Local $fp=StringSplit($filename,"\"), $fpp,$fps,$ros, $fp2,$fps2,$string,$foo,$line,$ros1,$ros2,$ros3
       
        If $fp[$fp]<>"" then
                $fpp=""
                $c=$fp
        Else
                $fpp="\"
                $c=$fp-1
        EndIf
       
        For $i=1 To $c
               
                If $fps<>"" Then$fps &= "\"
                $fps &= $fp[$i]
               
                $ros = $fp[$i]
                $ros = StringSplit($ros,".")
                If @error<>1 Then
                        If _StringLen($ros)<9 And _StringLen($ros)<4 And $ros<3 Then ContinueLoop ;
                Else
                        If _StringLen($fp[$i])<9 Then ContinueLoop ;字符长度9个以内不处理,处理也是错误!
                EndIf

                If $i>1 Then

                        $fp2=StringSplit($fps,"\")
                        $fps2=""
                        For $j=1 To $fp2-1
                                $fps2 &= $fp2[$j]&"\"
                        Next
                        $string='FOR /F "eol=; tokens=2,3* delims=]" %i in ('&"'dir/x/n "& $fps2 &' ^| find /i /n "'& $fp2[$fp2] &'" '&"') do @ECHO %i"
                        $foo = Run(@ComSpec & " /c "&$string, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
                       
                        $line=""
                        While 1
                                $line &= StdoutRead($foo)
                                If @error Then ExitLoop;(StdioClose($foo))
                        Wend
                        $line = StringSplit ( $line, @CR, 0)
                       
                        $ros3=""
                        For $j=1 To $line
                                $ros3 = $line[$j]
                                $ros1 =StringReplace($ros3, _StringLeft($ros3, 36) ,"")
                                $ros2=StringReplace($ros1, _StringLeft($ros1, 13) ,"")
                                $ros1 =StringStripWS ( _StringLeft($ros1, 13) , 8 )
                                If $j > 1 Then
                                        If StringInStr($ros2,$fp2[$fp2]) >1Then ExitLoop ;匹配以空白符开头的名称(差出1字节)
                                Else
                                        If StringInStr($ros2,$fp2[$fp2]) =1Then ExitLoop
                                EndIf

                        Next
                       
                        $fps = $fps2&$ros1
                EndIf

        Next

        If FileExists($fps&$fpp) Then Return $fps&$fpp ;"检测文件存在!返回字符串"
        SetError(1)
        Return "" ;"错误!返回空 并设 @error=1 ,……指定的文件(夹)不存在.
       
EndFunc


Func _StringLen($string) ;计算字串长度
        Local $str=StringSplit($string,"")
        Local $len=0
        For $i=1 To $str
                $len += 1
                If StringIsASCII ($str[$i]) = 0 Then $len += 1
        Next
        Return $len
EndFunc


Func _StringLeft($string, $len) ;按长度左取字串
        Local $ret, $str = StringSplit($string,"")
        $x=1
        Do
                If $x<$str Then
                        $ret &= $str[$x]
                        If StringIsASCII ($str[$x]) = 0 Then $len -= 1
                EndIf
                $x += 1
                $len -= 1
        Until $len <= 0
        If $ret="" Then Return SetError(1)
        Return $ret
EndFunc


_ddqs. 发表于 2010-10-30 14:52:49


;取短名应用示例:
;-------------------------->

#include <Constants.au3>

$f = 'E:\我的文档\ 欢迎使用 DOS 系统...'
        DirCreate($f & './')

$f = _FileGetShortName($f) ;取回短名

$f &= '\来到.我的.控制台...'
        DirCreate($f & './')

$f = _FileGetShortName($f) ;取回短名

#include <Process.au3>
_RunDOS('start "" "'&$f&'\"') ;打开文件夹

;-------------------------->


_ddqs. 发表于 2010-10-30 15:06:37

本帖最后由 _ddqs. 于 2010-11-1 00:09 编辑

_FileGetShortName.rar

;取短名应用示例:
;-------------------------->
#include <Constants.au3>
#include <_FileGetShortName.au3> ;并入更名后的取名脚本


$f = 'g:\我的文档\ 欢迎使用 DOS 系统...'
      DirCreate($f & './')

$f = _FileGetShortName($f) ;取回短名
$f &= '\来到.我的.控制台...'
      DirCreate($f & './')

$f = _FileGetShortName($f) ;取回短名
$f &= '\图片收藏.dir'
      DirCreate($f & './')


#include <Process.au3>

$f = _FileGetShortName($f) ;取回短名

If Not @error Then _RunDOS('start "" "'&$f&'\."') ;正常打开上行语句返回值的文件夹
If @error Then Exit(MsgBox(0,0,"不存在"))

_RunDOS('start "" "'&$f&'\"') ;打开文件夹……不加条件检测,当变量为空时以斜杆结尾会打开:脚本所在的根目录
_RunDOS('start "" "'&$f&'."') ;打开文件夹……不加条件检测,当变量为空时以点结尾会打开:脚本所在的目录



;-------------------------->

_ddqs. 发表于 2010-11-12 17:29:55

#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_icon=C:\WINDOWS\system32\SHELL32.dll|-166
#AutoIt3Wrapper_Res_Comment=拖到上面放开……以短名方式打开文件或文件夹(不支持网络路径),特殊名称也可以!
#AutoIt3Wrapper_Res_Description=_ddqs. @ www.autoitx.com
#AutoIt3Wrapper_Res_Fileversion=20101112.1.0.3
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=你说
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
;拖到上面放开……以短名方式打开文件或文件夹(不支持网络路径),特殊名称也可以!
#include <_FileGetShortName.au3> ;并入更名后的取名脚本



If $Cmdline < 1 Then Exit
If StringInStr($Cmdline, "\\")>0Then Exit
Run( @ComSpec &' /c start "" "'& _FileGetShortName($Cmdline) &'."' ,@SystemDir ,@SW_HIDE )


afan 发表于 2010-11-12 17:31:06

LZ真是执着哦~ ^ ^
页: [1] 2
查看完整版本: 利用DOS流取短名的函数(畸形名称也可以)(纯练手产物,结果14楼)[已解决]