2012-01-03 11 views
1

Windows\System32\drivers\etcフォルダ内のHOSTSファイルで動作するアプリケーションがあります。ただし、ドライブC:にWindowsがインストールされていない可能性があるため、パスをC:\Windows\System32にハードコーディングする必要はありません。Windowsディレクトリ定義

私は%WinDir%\system32\drivers\etc\hostsを使用しようとしましたが、これはコード内の変数で使用されても展開されません。

hostsファイルへのパスとして%WinDir%\system32\drivers\etc\hostsを使用すると、パスをハードコードする必要はありません。プラットフォームに固有のものですW1002シンボル 'TFileAttributes':

もう一つの問題は、コンパイルが成功に私は

[DCC警告] ApplicationWizard01.pas(67)のような1つの警告を受けているということです。

コードはここhere

は私の新しいコードでの回答で示されています:

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; 
+0

また、下記の私の回答の更新コードを参照してください。 –

答えて

4

%Windir%\System32を使用しないでください。特定のフォルダ、GetSystemDirectoryを見つけるために設計されたWindows APIの関数を使用します。これはWindowsの単位で定義されています。

これまでの回答で問題が発生していたので、完全にコンパイルされたコードのコピーがありました(私は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} 
+1

+1 WinAPIを使用してください – Kromster

+0

私はあなたのsuggessionとして試してみました。しかし、次のエラーが発生しました。 "[DCCエラー] KoushikHalder01.pas(58):E2003宣言されていない識別子: 'CheckTrailingPathDelimiter' on" PathAndFileName:= CheckTrailingPathDelimiter(GetSysDir)+ 'drivers \ etc \ hosts'; "行と "[DCCエラー] KoushikHalder01.pas(59):E2066演算子またはセミコロン" on "属性が欠落しています:= [];"ライン。私を助けてください。上記のコードを追加しました。 –

+1

私は以前に修正する方法を教えてくれたことを警告するコンパイラの修正を含む)を書き直し、答えを更新しました。バックスラッシュ機能の問題は私のものでした。関数名が間違っていたことを思い出し、別の問題を予期していた私の以前の答えにその場で追加しました。正しい機能を使用するように修正されました。これはRTLの組み込み関数なので、コードを追加したり宣言したりする必要はありません。それをそのまま使用してください。完全にコンパイルされます。 –

0

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

  1. セットの再sultの長さを255バイトに広げるか、または幅を広げるために512を使用し、バッファ全体をNULL文字で塗りつぶす#0
  2. OSからのウィンドウフォルダを最初のcharのポインタに要求し、バッファの長さをcharsの長さに設定します。文字列の内容を最初のヌルバイトに破棄し、文字列を破棄します。実際の最初のnullbyteは文字列の次のcharです。なぜなら最初の行はすべてをnullcharsで埋めているからです。

    ps:nullバイトを無視した後の文字列内のすべてが無視され、nullバイト文字が含まれます。

+0

これは、Windowsインストールフォルダへのパスを取得します。 OPは、代わりにSystem32フォルダへのパスを取得するように求めました。 –

+0

GetWindowsDirectoryは簡単に同じパラメータでGetSystemDirectoryに置き換えることができます! –

関連する問題