Reputation: 455
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;
Upvotes: 2
Views: 6586
Reputation: 11
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!
Upvotes: 0
Reputation: 125767
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}
Upvotes: 6