DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: ahttp123
今日帖子: 22
在线用户: 17
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 9:34:31
标题:
如何处理文件名看起来是空格显示是问号的文件? 浏览:1905
加入我的收藏
楼主: 需要获取一个文件夹下的所有文件,并打开其中一个文件,
目前获取到的文件名显示存在问号,所以使用ShellExecute命令打开无效,
这个文件名在资源管理器下,一个位置上显示是空格,但是在程序中同样的位置显示的是问号
,请问要如何处理才能使用ShellExecute命令打开这个xlsx文件
此帖子包含附件:ken0137_2022102793431.zip 大小:6.3K
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 9:39:27
1楼: 如图所示
此帖子包含附件:
JPEG 图像
大小:73.4K
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/27 9:41:17
1楼: 我猜是Unicode之类惹的祸。

ShellExecute方法中文本参数是PChar类型的。 
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,Directory: PChar; ShowCmd: Integer): HINST; stdcall;


ShellExecute();
ShellExecuteA();
ShellExecuteW();
ShellExecuteEx();
ShellExecuteExA();
ShellExecuteExW();
----------------------------------------------
z@S7
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2022/10/27 9:52:24
2楼: 文件名带空格,ShellExecute 打开它时,要加双引号。
ShellExecute(0,'Open',PChar('"055 H.xlsx"'),nil,nil,SW_SHOWNORMAL);
试了下可以正常打开
----------------------------------------------
-
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2022/10/27 9:58:53
3楼: //一点问题都没有呢,亲
//delphi 11.2
//win11_x64
uses
  System.IOUtils,
  Winapi.ShellAPI
  ;

procedure TForm1.Button1Click(Sender: TObject);
begin
  var LArr := TDirectory.GetFiles(Edit1.Text);
  for var s in LArr do
  listbox1.Items.Add(s);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.Text := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
  var s := ListBox1.Items[ListBox1.ItemIndex];
  ShellExecute(0, 'OPEN', PChar(s), nil, nil, SW_SHOWNORMAL);
end;
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。又不靠它 delphi 吃饭,怕甚?
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 10:07:14
4楼: @sail2000,D7下要如何获取运行呢?
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 10:10:35
5楼: 我是使用EnumFInQueue获取文件夹下的所有文件,将路径保存到本地数据库中,需要的时候在读取路径,使用ShellExecute执行打开,(Delphi7),现在获取文件名的时候就出现了文件名问号的问题。
procedure EnumFInQueue(path: PChar; FExt: string; var FList: TStringList);
var
   searchRec: TSearchRec;
   found: Integer;
   tmpStr: string;
   curDir: string;
   dirs: TQueue;  //Contnrs
   pszDir: PChar;
begin
   dirs := TQueue.Create; //创建目录队列
   dirs.Push(path); //将起始搜索路径入队
   pszDir := dirs.Pop;  
   curDir := StrPas(pszDir); //出
   while (True) do
   begin
      tmpStr := curDir + '\*.*';
      found := FindFirst(tmpStr, faAnyFile, searchRec);//在当前目录查找第一个文件、子目录
      while found = 0 do //找到了一个文件或目录后  
      begin
        if (FExt='') then
        begin
          if ((searchRec.Attr and faDirectory) <> 0) then
          if (searchRec.Name <> '.') and (searchRec.Name <> '..') then
          begin
          FList.Add(searchRec.Name)
          end;
        end else
        begin
          if ((searchRec.Attr and faDirectory) = 0) then
          if FExt = '.*' then
          FList.Add(searchRec.Name)
          else
          begin
          if SameText(RightStr(curDir + '\' + searchRec.Name, Length(FExt)), FExt) then   //StrUtils
          FList.Add( ChangeFileExt(ExtractFileName(searchRec.Name),''));
          end;
        end;
         found := FindNext(searchRec);
      end;
      if dirs.Count > 0 then 
      begin
         pszDir := dirs.Pop;  
         curDir := StrPas(pszDir);
         StrDispose(pszDir);  
      end
      else 
         break;
   end;
   dirs.Free;
   FindClose(searchRec);
end;
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/27 10:20:34
6楼: 你这个文件名,中间还倒了一手。
我建议你试试,直接获取文件夹下的文件名,然后把这个文件名传给ShellExecute,看看是啥效果。
----------------------------------------------
z@S7
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2022/10/27 10:30:41
7楼: D7是不支持UNICODE的,尤其VCL控件,你需要装TNT的VCL控件,用TTntEdit代替TEDIT,并且在搜索目录的时,使用TSearchRecW代替TSearchRec,使用WideString代替String,使用ShellExecuteW代替ShellExecute,注意传入参数时,使用PWideChar来转换WideString而不是String。
----------------------------------------------
简单做人,认真做事。
作者:
男 doersoft (hnysoft.com) ★☆☆☆☆ -
普通会员
2022/10/27 12:27:56
8楼: 换支持unicode的IDE或用TNT控件.
----------------------------------------------
delphi|vue|golang hnysoft|hnyerp+mes+srm
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 14:27:18
9楼: 我这里还有一个问题就是,使用3楼的方式,那么数据值存入到sqllite中去,就又变成问号了,要如何存储这个文件名称?
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/27 14:53:09
10楼: 能够给个可用于D7版本的TNT?
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 tuesdays (Tuesday) ▲▲▲▲△ -
普通会员
2022/10/27 14:59:58
11楼: 我只想告诉你们, 这种命名在win下就是非法的, 即使出现这种文件, 
果断一点, 弹错误告诉用户请使用正确的文件名,  完毕. 

用个比如, 就是99%的正确, 1%的人总是想搞事, 称之为黑客. 设计原则就是, 程序不要崩, 该提示, 该拒绝, 果断拒绝...
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2022/10/27 15:20:12
12楼: tuesdays 你还真说错了。
unicode俗称万国码,是微软为了统一各国编码而设计的。
例如 中文GB2312,GBK扩展,ASCII等,计算机发展初期,每个国家
都制定了一套编码,因此导致你使用另外一个国家编码库就无法正确
显示,显示为方框的问题,微软为了搞定这种乱象制定了UNICODE这种
万国码,保证各种语言的字符都能正常显示。

原则上来说,文件命名可以使用各种语言编码,但D7不支持UNICODE,
所以导致路径中有非标准编码就无法访问显示为?的问题,这是D7的问
题而不是WINDOWS或者文件命名的问题。

处理这个最简单的方法使用DELPHI 2009开始的版本,这是最简单的。
如果非要用D7,那么注意3点即可;
1)所有的STRING、PCHAR都改为WIDESTRING,PWIDECHAR
2)所有用到的API都使用xxxW的版本函数,而不是默认的。
3)如果非要显示,就安装TNT控件,用TNT的控件代替标准化控件。

因为做了很多年文件备份、加解密,D6/7时代都遇到过,如果你看不明
白,也没办法了。
----------------------------------------------
简单做人,认真做事。
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2022/10/27 17:38:29
13楼: 文件名和文件内容一样,确实可以使用各种编码。
问题是文件名难道不该使用操作系统使用的文件名编码。

就算Windows下也可以不用GBK,能设成UTF8。

但如果不使用操作系统的编码,显示乱码无所谓。
到传FTP之类需要转换编码的地方,鬼知道这个文件名是什么编码呢。

各种程序默认当然是用操作系统设置的编码。
所以tuesdays说的也不算错吧……

统一本来是好事儿,但是我们国家嘛,咳咳,总是有自己标准的。
上升到法律问题了。。。
----------------------------------------------
Bye bye DDRFAN...
作者:
男 tuesdays (Tuesday) ▲▲▲▲△ -
普通会员
2022/10/27 19:57:02
14楼: @jackalan (nVicen)
先不要谈unicode, 看图片吧, 
如果代码都识别不了的文件, 直接弹错误准没错..
此帖子包含附件:
PNG 图像
大小:38.0K
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/28 5:48:48
15楼: you can try some like this:

uses
  System.IOUtils;
...

  LFileName      : string;
  LMyInvalidChars: TArray<char>;
begin
  LFileName := 'hello|world?.~\txt'; // ExtractFileName(xxxx) -- just name!!!
  //
  // TPath.GetInvalidPathChars  --> ExtractFileDir(xxxx) -- just path!!!
  LMyInvalidChars := TPath.GetInvalidFileNameChars + ['~', '[', ']'];
  //
  for var i: integer := 1 to LFileName.Length do
    for var C in LMyInvalidChars do
      if (LFileName[i] = C) then
        LFileName[i] := 'X';
  //
  ShowMessage(LFileName);

----------
Warning about this:
  TPath.GetInvalidFileNameChars( xxx, FALSE /TRUE );
  TPath.GetInvalidPathChars( xxx, FALSE /TRUE );

ex.: 
  TPath.GetInvalidFileNameChars('c:\test.exe', false) = TRUE!!!! --> because the full-path+filename together
此帖子包含附件:
PNG 图像
大小:31.8K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2022/10/28 14:50:19
16楼: 你用DELPHI 2009以后的版本,不管哪个版本都不会有问题,难道这是WINDOWS的问题?
----------------------------------------------
简单做人,认真做事。
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2022/10/28 16:10:34
17楼: @14楼
文件名不支持某些字符 vs 文件名用了不同于操作系统的编码
是不同的情况呢。

@15楼
楼主用的是Delphi7,String取到文件名的时候,因为编码不同,这时就已经错了。
后面再判断处理都没用了。

JoJo:欧拉欧拉欧拉欧拉……
Dio:没用没用没用没用……
----------------------------------------------
Bye bye DDRFAN...
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/28 21:37:15
18楼: maybe help: Delphi7 and unicode

"I need to write a program which will browse through strings of various lengths and select only those which are written using symbols from set defined by me (particularly Japanese letters). Strings will contain words written in different languages (German, French, Arabic, Russian, English etc). Obviously there is huge number of possible characters. I do not know which structure to use for that? I am using Delphi 7 right now. Can anybody suggest how to write such program?
"
https://stackoverflow.com/questions/2281223/working-with-unicode-strings-in-delphi-7


12


Obviously you would be better off with Delphi 2010, since the VCL in delphi 7 is not aware of Unicode strings. You can use WideString types, and WideChar types in Delphi 7, and you can install a component set like the TNT Unicode Components to help you create a user interface that can display your results.

For a very-large-set type, consider using a bit array like TBits. A bit array of length 65536 would hold enough to contain every UTF-16 code-point. Checking if Char X is in Set Y, would be basically:

function WideCharsInSet( wcstr:WideString; wcset:TBits):Boolean;
var
 n:Integer;
 wc:WideChar;
begin
result := false;
for n := 1 to Length(wcstr) do begin
  wc := wcstr[n];
  if wcset[Ord(wc)] then
      result := true;
end;
end;

procedure Demo;
var
 wcset1:TBits;
 s:WideString;
begin
 wcset1 := TBits.Create;
 try
  // 1157 - Hangul Korean codepoint I found with Char Map
    wcset1[1157] := true;         
    // go get a string value s:
    s := WideChar(1157);
// return true if at least one element in set wcset is found in string s:
    if WideCharsInSet(s,wcset1) then begin
        Application.MessageBox('Found it','found it',MB_OK);
    end;

 finally
  wcset1.Free;
 end;

end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 ken0137 (顺眼即佛) ★☆☆☆☆ -
普通会员
2022/10/31 9:34:45
19楼: 若是先不管文件名的显示,我想先想文件名存储起来,再读取,再做其他操作,比如删除,运行,那么这个文件名应该如何编码储存(本地数据库)和读取,若是按照常规操作的话,必然是不可行的
----------------------------------------------
只会简单使用,并未精通深入
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/31 11:44:19
20楼: If your Database can define the "CHARSET" for a field, you can store it in a Field  with Charset: NONE or OCTETS 

Charset in a Database creation of table-fields in Firebird:

NONE: Plain octets, no character set applied. With
this character set setting, Firebird is unable to
perform conversion operations like UPPER() correctly
on anything other than the standard 26 latin letters.

OCTETS: Same as NONE. Cannot be used as client
connection character set. Space character is #x00

Ex. Firebird 

CREATE TABLE MYTABLE (
  ID          INTEGER NOT NULL,
  ... 
  MYFIELD_CHARSET_NONE  VARCHAR(200) CHARACTER SET NONE NOT NULL
);

None character convertion is done in "MYFIELD_CHARSET_NONE" field!
it's stored some like a "byte" (not a specific chars for a specific charset)

NOTE: in Firebird, DIALECT 3 is used for all user-databases. But, DIALECT 2 is used internally in low-level to convertions between DIALECT 1 and 3.  DIALECT 2 used OCTECTS!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 magiewang (magiewang) ▲▲▲△△ -
普通会员
2022/10/31 14:29:52
21楼: @ken0137 WIDESTRINGTOUTF8
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行121.0938毫秒 RSS