Определение каталога Windows - PullRequest
2 голосов
/ 03 января 2012

У меня есть приложение, которое будет работать с файлом HOSTS в папке Windows\System32\drivers\etc. Однако я не хочу жестко кодировать путь к 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;

Ответы [ 2 ]

5 голосов
/ 03 января 2012

Не используйте %Windir%\System32.Используйте функцию Windows API, специально предназначенную для поиска этой папки, GetSystemDirectory .Это определено в модуле 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}
0 голосов
/ 09 января 2015

Просто:

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

  1. устанавливает длину результата в 255 байт или 512 для расширения и заполняет весь буфер нулевыми символами # 0
  2. запрашивает папку Windows из ОС на указатель первого символа и устанавливает длину буфера равной длине символов, после чего, когда строка больше не используется, очиститель уничтожит содержимое строки первым нулевым байтом, а затем уничтожит строку. На самом деле первый нуль-байт - следующий символ строки, потому что первая строка заполняет все нуль-символами.

    ps: все в строке после nullbyte игнорируется, включая nullbyte char!

...