Windows目录定义
我有一个应用程序可以使用 Windows\System32\drivers\etc
文件夹中的 HOSTS
文件。但是,我不想将路径硬编码到 C:\Windows\System32
,因为 Windows 可能未安装在驱动器 C: 上。
我尝试使用 %WinDir%\system32\drivers\etc\hosts
,但是当它在我的代码中的变量中使用时,它不会被扩展。
如何使用 %WinDir%\system32\drivers\etc\hosts
作为 hosts
文件的路径,这样我就不必对路径进行硬编码?
另一个问题是,在成功编译后,我收到了一个警告:
[DCC 警告] ApplicationWizard01.pas(67):W1002 符号 “TFileAttributes”特定于平台。
代码显示在答案此处
这是我的新代码:
unit KoushikHalder01;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
Vcl.ComCtrls;
type
TForm01 = class(TForm)
Label01: TLabel;
Edit01: TEdit;
Edit02: TEdit;
BitBtn01: TBitBtn;
BitBtn02: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure BitBtn01MouseEnter(Sender: TObject);
procedure BitBtn02MouseEnter(Sender: TObject);
procedure BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn01MouseLeave(Sender: TObject);
procedure BitBtn02MouseLeave(Sender: TObject);
procedure BitBtn02Click(Sender: TObject);
procedure BitBtn01Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form01: TForm01;
implementation
{$R *.dfm}
uses System.IOUtils;
procedure TForm01.BitBtn01Click(Sender: TObject);
function GetSysDir: string;
function IncludeTrailingPathDelimiter(const S: string): string;
var
Attributes: TFileAttributes;
SL: TStringList;
Idx: Integer;
Buffer: array[0..MAX_PATH] of Char;
PathAndFileName : String;
begin
GetSystemDirectory(Buffer, MAX_PATH - 1);
SetLength(Result, StrLen(Buffer));
Result := Buffer;
PathAndFileName := CheckTrailingPathDelimiter(GetSysDir) + 'drivers\etc\hosts`;
Attributes := [];
TFile.SetAttributes('PathAndFileName', Attributes);
SL := TStringList.Create;
try
SL.LoadFromFile('PathAndFileName');
if
SL.IndexOf('10.220.70.34 VIRTSDP25') <> -1
then
begin
Edit02.Font.Color := clRed;
Edit02.Text := 'Your Host File Has Already Been Modified Successfully.';
end;
if
SL.IndexOf('10.220.70.34 VIRTSDP25') = -1
then
begin
SL.Add('10.220.70.34 VIRTSDP25');
Edit02.Font.Color := clGreen;
Edit02.Text := 'Your Host File Has Been Modified Successfully.';
end;
if
SL.IndexOf('10.220.70.32 BSNLESDP25A') = -1
then
SL.Add('10.220.70.32 BSNLESDP25A');
if
SL.IndexOf('10.220.70.33 BSNLESDP25B') = -1
then
SL.Add('10.220.70.33 BSNLESDP25B');
if
SL.IndexOf('10.220.70.34 VIRTBSNLESDP25') = -1
then
SL.Add('10.220.70.34 VIRTBSNLESDP25');
if
SL.IndexOf('10.220.70.34 KOSDPTwentyfive.bsnl.in.net') = -1
then
SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.in.net');
if
SL.IndexOf('10.220.70.34 KOSDPTwentyfive.bsnl.net.in') = -1
then
begin
SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
SL.SaveToFile('PathAndFileName');
end;
finally
SL.Free;
end;
Include(Attributes, TFileAttribute.faSystem);
Include(Attributes, TFileAttribute.faReadOnly);
TFile.SetAttributes('PathAndFileName', Attributes);
end;
I have an application that will work with the HOSTS
file in the Windows\System32\drivers\etc
folder. However, I don't want to hard code the path to C:\Windows\System32
, because Windows might not be installed on drive C:.
I tried using %WinDir%\system32\drivers\etc\hosts
, but this doesn't get expanded when it's used in the variable in my code.
How can I use %WinDir%\system32\drivers\etc\hosts
as the path to the hosts
file so I don't have to hard-code the path?
Another problem is that on successful compilation I have received one warning as
[DCC Warning] ApplicationWizard01.pas(67): W1002 Symbol
'TFileAttributes' is specific to a platform.
Code is shown in the answer here
Here is my new code :
unit KoushikHalder01;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
Vcl.ComCtrls;
type
TForm01 = class(TForm)
Label01: TLabel;
Edit01: TEdit;
Edit02: TEdit;
BitBtn01: TBitBtn;
BitBtn02: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure BitBtn01MouseEnter(Sender: TObject);
procedure BitBtn02MouseEnter(Sender: TObject);
procedure BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn01MouseLeave(Sender: TObject);
procedure BitBtn02MouseLeave(Sender: TObject);
procedure BitBtn02Click(Sender: TObject);
procedure BitBtn01Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form01: TForm01;
implementation
{$R *.dfm}
uses System.IOUtils;
procedure TForm01.BitBtn01Click(Sender: TObject);
function GetSysDir: string;
function IncludeTrailingPathDelimiter(const S: string): string;
var
Attributes: TFileAttributes;
SL: TStringList;
Idx: Integer;
Buffer: array[0..MAX_PATH] of Char;
PathAndFileName : String;
begin
GetSystemDirectory(Buffer, MAX_PATH - 1);
SetLength(Result, StrLen(Buffer));
Result := Buffer;
PathAndFileName := CheckTrailingPathDelimiter(GetSysDir) + 'drivers\etc\hosts`;
Attributes := [];
TFile.SetAttributes('PathAndFileName', Attributes);
SL := TStringList.Create;
try
SL.LoadFromFile('PathAndFileName');
if
SL.IndexOf('10.220.70.34 VIRTSDP25') <> -1
then
begin
Edit02.Font.Color := clRed;
Edit02.Text := 'Your Host File Has Already Been Modified Successfully.';
end;
if
SL.IndexOf('10.220.70.34 VIRTSDP25') = -1
then
begin
SL.Add('10.220.70.34 VIRTSDP25');
Edit02.Font.Color := clGreen;
Edit02.Text := 'Your Host File Has Been Modified Successfully.';
end;
if
SL.IndexOf('10.220.70.32 BSNLESDP25A') = -1
then
SL.Add('10.220.70.32 BSNLESDP25A');
if
SL.IndexOf('10.220.70.33 BSNLESDP25B') = -1
then
SL.Add('10.220.70.33 BSNLESDP25B');
if
SL.IndexOf('10.220.70.34 VIRTBSNLESDP25') = -1
then
SL.Add('10.220.70.34 VIRTBSNLESDP25');
if
SL.IndexOf('10.220.70.34 KOSDPTwentyfive.bsnl.in.net') = -1
then
SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.in.net');
if
SL.IndexOf('10.220.70.34 KOSDPTwentyfive.bsnl.net.in') = -1
then
begin
SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
SL.SaveToFile('PathAndFileName');
end;
finally
SL.Free;
end;
Include(Attributes, TFileAttribute.faSystem);
Include(Attributes, TFileAttribute.faReadOnly);
TFile.SetAttributes('PathAndFileName', Attributes);
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要使用
%Windir%\System32
。使用专门设计的 Windows API 函数来查找该文件夹 获取系统目录。它是在Windows单元中定义的;这是一个快速包装器(未在 XE2 上测试,但适用于 XE):由于您对我之前的答案有疑问,这里是代码的完整编译副本(我注释掉了您对
Edit02
的引用,所以你需要取消注释它们;其他一切都可以像在 XE2 下一样编译:Don't use the
%Windir%\System32
. Use the Windows API's function designed specifically to find that folder, GetSystemDirectory. It's defined in the Windows unit; here's a quick wrapper (not tested on XE2, but works on XE):Since you had problems with my previous answer, here's a fully-compiling copy of the code (I commented out your references to
Edit02
, so you'll need to uncomment them; everything else compiles just fine as is under XE2:简单地说:
function WindowsPath: string;
开始
SetLength(结果, MAX_PATH);
SetLength(结果, GetWindowsDirectory(@Result[1], MAX_PATH));
end;
从操作系统请求 Windows 文件夹到第一个字符的指针,并将缓冲区长度设置为字符长度,在此之后当字符串不再使用时,清理器将销毁字符串内容到第一个空字节,然后销毁字符串。实际上第一个空字节是字符串的下一个字符,因为第一行用空字符填充所有内容。
ps:忽略空字节之后字符串中的所有内容,包括空字节字符!
Simply :
function WindowsPath: string;
begin
SetLength(Result, MAX_PATH);
SetLength(Result, GetWindowsDirectory(@Result[1], MAX_PATH));
end;
requests windows folder from OS to pointer of first char, and sets length of buffer to chars length, after this when string no more used cleaner will destroy string content to first null byte, then destroys string. Actualy first nullbyte is next char of string because first line fills everything with nullchars.
ps: Everything in string after nullbyte ignored, nullbyte char including!