Windows目录定义

发布于 2024-12-24 01:35:45 字数 3936 浏览 2 评论 0原文

我有一个应用程序可以使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰ゝ天使的微笑 2024-12-31 01:35:46

不要使用%Windir%\System32。使用专门设计的 Windows API 函数来查找该文件夹 获取系统目录。它是在Windows单元中定义的;这是一个快速包装器(未在 XE2 上测试,但适用于 XE):

由于您对我之前的答案有疑问,这里是代码的完整编译副本(我注释掉了您对 Edit02 的引用,所以你需要取消注释它们;其他一切都可以像在 XE2 下一样编译:

uses 
  System.IOUtils;

function GetSysDir: string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
   GetSystemDirectory(Buffer, MAX_PATH - 1);
   SetLength(Result, StrLen(Buffer));
   Result := Buffer;
end;

{$WARN SYMBOL_PLATFORM OFF}
procedure TForm2.Button1Click(Sender: TObject);
var
  Attributes: TFileAttributes;
  SL: TStringList;
  Idx: Integer;
  PathAndFileName : String;
begin
   PathAndFileName := IncludeTrailingPathDelimiter(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
       SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
     SL.SaveToFile(PathAndFileName);
   finally
       SL.Free;
   end;
    Include(Attributes, TFileAttribute.faSystem);
    Include(Attributes, TFileAttribute.faReadOnly);
    TFile.SetAttributes(PathAndFileName, Attributes);
end;
{$WARN SYMBOL_PLATFORM ON}

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:

uses 
  System.IOUtils;

function GetSysDir: string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
   GetSystemDirectory(Buffer, MAX_PATH - 1);
   SetLength(Result, StrLen(Buffer));
   Result := Buffer;
end;

{$WARN SYMBOL_PLATFORM OFF}
procedure TForm2.Button1Click(Sender: TObject);
var
  Attributes: TFileAttributes;
  SL: TStringList;
  Idx: Integer;
  PathAndFileName : String;
begin
   PathAndFileName := IncludeTrailingPathDelimiter(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
       SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
     SL.SaveToFile(PathAndFileName);
   finally
       SL.Free;
   end;
    Include(Attributes, TFileAttribute.faSystem);
    Include(Attributes, TFileAttribute.faReadOnly);
    TFile.SetAttributes(PathAndFileName, Attributes);
end;
{$WARN SYMBOL_PLATFORM ON}
开始看清了 2024-12-31 01:35:46

简单地说:

function WindowsPath: string;
开始
SetLength(结果, MAX_PATH);
SetLength(结果, GetWindowsDirectory(@Result[1], MAX_PATH));
end;

  1. 将结果长度设置为 255 字节或 512 以实现最宽,并用空字符填充整个缓冲区 #0
  2. 从操作系统请求 Windows 文件夹到第一个字符的指针,并将缓冲区长度设置为字符长度,在此之后当字符串不再使用时,清理器将销毁字符串内容到第一个空字节,然后销毁字符串。实际上第一个空字节是字符串的下一个字符,因为第一行用空字符填充所有内容。

    ps:忽略空字节之后字符串中的所有内容,包括空字节字符!

Simply :

function WindowsPath: string;
begin
SetLength(Result, MAX_PATH);
SetLength(Result, GetWindowsDirectory(@Result[1], MAX_PATH));
end;

  1. set's result length to 255 bytes or 512 for widesting and fills whole buffer with null chars #0
  2. 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文