Search code examples
delphidelphi-xe2

Windows Directory Definition


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;

Solution

  • 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}