如何共享应用程序和关联的数据文件
How to share an application and associated datafile
我使用 delphi 社区版编写了一个程序 (firemonkey)。我想分享这个程序,但是我的朋友们要下载的 .exe 文件必须时不时地访问一个文本文件来检索字符串。在编写程序时,我使用事件处理程序在启动时加载文本文件:
tform3.formCreate(发件人:Tobject);
...
assignfile(myfile,('C:** ********.txt));
...
期间工作得很好
设计阶段。
作为一个爱好者,我现在发现自己被困住了。如果我使用 INNO 安装编译器创建一个安装程序,我打算这样做,我不能对数据有相同的硬连线引用 ('C:*****)文件的位置。我需要的是更改上面的代码,以便 .exe 文件可以找到支持的数据文件,而不管该 .exe 文件(和数据文件)在其他人的 PC 上的最终位置。
我该怎么做?即我需要什么代码(代替上面的代码)来确保我分发的安装程序将安装一个可以找到它引用的数据文件的 .exe 文件?
任何帮助,非常感谢。还在学习中。
Read-only 访问
如果数据文件应该始终以read-only 模式打开,最简单的解决方案是将其放在*.exe 文件旁边。然后,在运行时,您动态找到 *.exe 文件的路径并修改它以找到数据文件的路径。例如,
uses
IOUtils;
procedure TForm1.FormCreate(Sender: TObject);
var
FileName: string;
begin
FileName := TPath.Combine(ExtractFilePath(ParamStr(0)), 'data.txt');
ShowMessage(TFile.ReadAllText(FileName, TEncoding.UTF8));
end;
ParamStr(0)
包含*.exe文件的路径,如
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\Project1.exe'
那么ExtractFilePath(ParamStr(0))
就是
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\'
最后,TPath.Combine(ExtractFilePath(ParamStr(0)), 'data.txt')
是
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\data.txt'
确保安装程序将数据文件放在 *.exe 文件旁边。
读写权限
如果我们谈论的是每个用户都需要更改(通过软件)的设置文件或其他文件,则不能将其放在 *.exe 文件旁边,因为 *.exe 文件通常位于Program Files 文件夹,它是只读的。另外,Program Files文件夹只有一个,但PC上可能有很多用户,每个用户都应该有自己的一份。
解决方法是将文件保存在用户自己的文件夹中,具体为AppData
文件夹:
FileName := TPath.GetHomePath + '\Mariner\My Word Processor App\Settings\settings.ini';
(使用不同的路径构建方法)。
在我的系统上,这变成了
'C:\Users\Andreas Rejbrand\AppData\Roaming\Mariner\My Word Processor App\Settings\settings.ini'
您的安装程序 (Inno Setup) built-in 支持在此位置放置文件。
如果只读访问,也可以考虑将其作为资源添加到可执行文件中。这样一来,您就可以简单地分发此可执行文件而无需安装程序。
Delphi Dabbler 有一个示例,但我发现它有点令人困惑。无论如何我都会 link to it (PDF)。
您可以让用户select 保存文件的位置。如果文件是针对每个单独用户的,则建议使用 AppData 文件夹;如果文件必须在不同用户之间共享,则建议使用 CommonAppData。
当使用selected 数据文件目标时,您可以将其保存到 INI 文件中。 INI 文件可以在不询问用户的情况下存储到注册表或保存在 AppData 文件夹或 ProgramData 文件夹中的 INI 文件。
这里是一段源代码片段,用于获取那些特殊文件夹:
const
SectionWindow = 'Window';
SectionData = 'Data';
CompanyFolder = 'YourCompanyName';
constructor TForm1.Create(AOwner: TComponent);
var
CommonPath : array [0..MAX_PATH] of Char;
LocalPath : array [0..MAX_PATH] of Char;
LangFileName : String;
begin
SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, SHGFP_TYPE_CURRENT, @CommonPath[0]);
SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, @LocalPath[0]);
FIniSection := SectionWindow;
FIniSectionData := SectionData;
FAppName := ChangeFileExt(ExtractFileName(Application.ExeName), '');
FCommonAppData := IncludeTrailingPathDelimiter(CommonPath) +
CompanyFolder + '\' + FAppName + '\';
FLocalAppData := IncludeTrailingPathDelimiter(LocalPath) +
CompanyFolder + '\' + FAppName + '\';
FIniFileName := FLocalAppData + FAppName + '.ini';
ForceDirectories(FCommonAppData);
ForceDirectories(FLocalAppData);
inherited Create(AOwner);
end;
我使用 delphi 社区版编写了一个程序 (firemonkey)。我想分享这个程序,但是我的朋友们要下载的 .exe 文件必须时不时地访问一个文本文件来检索字符串。在编写程序时,我使用事件处理程序在启动时加载文本文件:
tform3.formCreate(发件人:Tobject); ... assignfile(myfile,('C:** ********.txt)); ...
期间工作得很好 设计阶段。
作为一个爱好者,我现在发现自己被困住了。如果我使用 INNO 安装编译器创建一个安装程序,我打算这样做,我不能对数据有相同的硬连线引用 ('C:*****)文件的位置。我需要的是更改上面的代码,以便 .exe 文件可以找到支持的数据文件,而不管该 .exe 文件(和数据文件)在其他人的 PC 上的最终位置。
我该怎么做?即我需要什么代码(代替上面的代码)来确保我分发的安装程序将安装一个可以找到它引用的数据文件的 .exe 文件?
任何帮助,非常感谢。还在学习中。
Read-only 访问
如果数据文件应该始终以read-only 模式打开,最简单的解决方案是将其放在*.exe 文件旁边。然后,在运行时,您动态找到 *.exe 文件的路径并修改它以找到数据文件的路径。例如,
uses
IOUtils;
procedure TForm1.FormCreate(Sender: TObject);
var
FileName: string;
begin
FileName := TPath.Combine(ExtractFilePath(ParamStr(0)), 'data.txt');
ShowMessage(TFile.ReadAllText(FileName, TEncoding.UTF8));
end;
ParamStr(0)
包含*.exe文件的路径,如
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\Project1.exe'
那么ExtractFilePath(ParamStr(0))
就是
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\'
最后,TPath.Combine(ExtractFilePath(ParamStr(0)), 'data.txt')
是
'C:\Users\Andreas Rejbrand\Documents\Embarcadero\Studio\Projects\test\Win32\Debug\data.txt'
确保安装程序将数据文件放在 *.exe 文件旁边。
读写权限
如果我们谈论的是每个用户都需要更改(通过软件)的设置文件或其他文件,则不能将其放在 *.exe 文件旁边,因为 *.exe 文件通常位于Program Files 文件夹,它是只读的。另外,Program Files文件夹只有一个,但PC上可能有很多用户,每个用户都应该有自己的一份。
解决方法是将文件保存在用户自己的文件夹中,具体为AppData
文件夹:
FileName := TPath.GetHomePath + '\Mariner\My Word Processor App\Settings\settings.ini';
(使用不同的路径构建方法)。
在我的系统上,这变成了
'C:\Users\Andreas Rejbrand\AppData\Roaming\Mariner\My Word Processor App\Settings\settings.ini'
您的安装程序 (Inno Setup) built-in 支持在此位置放置文件。
如果只读访问,也可以考虑将其作为资源添加到可执行文件中。这样一来,您就可以简单地分发此可执行文件而无需安装程序。
Delphi Dabbler 有一个示例,但我发现它有点令人困惑。无论如何我都会 link to it (PDF)。
您可以让用户select 保存文件的位置。如果文件是针对每个单独用户的,则建议使用 AppData 文件夹;如果文件必须在不同用户之间共享,则建议使用 CommonAppData。
当使用selected 数据文件目标时,您可以将其保存到 INI 文件中。 INI 文件可以在不询问用户的情况下存储到注册表或保存在 AppData 文件夹或 ProgramData 文件夹中的 INI 文件。
这里是一段源代码片段,用于获取那些特殊文件夹:
const
SectionWindow = 'Window';
SectionData = 'Data';
CompanyFolder = 'YourCompanyName';
constructor TForm1.Create(AOwner: TComponent);
var
CommonPath : array [0..MAX_PATH] of Char;
LocalPath : array [0..MAX_PATH] of Char;
LangFileName : String;
begin
SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, SHGFP_TYPE_CURRENT, @CommonPath[0]);
SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, @LocalPath[0]);
FIniSection := SectionWindow;
FIniSectionData := SectionData;
FAppName := ChangeFileExt(ExtractFileName(Application.ExeName), '');
FCommonAppData := IncludeTrailingPathDelimiter(CommonPath) +
CompanyFolder + '\' + FAppName + '\';
FLocalAppData := IncludeTrailingPathDelimiter(LocalPath) +
CompanyFolder + '\' + FAppName + '\';
FIniFileName := FLocalAppData + FAppName + '.ini';
ForceDirectories(FCommonAppData);
ForceDirectories(FLocalAppData);
inherited Create(AOwner);
end;