DelphiのWindowsサービスのDescriptionの設定方法について

解決


のぶ  2019-10-29 16:37:49  No: 148351

Windowsサービスを登録して「説明(Description)」を設定しようとしたのですが、
例えば'test'と指定しても't'で設定されてしまいます。
Delphi3.1だと問題はなかったのですが、Dephi10.1で現象が出ます。
どなたか原因を教えていたけるとありがたいです。

例)

type
  TSERVICE_DESCRIPTION = packed record
    lpDescription: PChar;
  end;

var
  schService: SC_HANDLE;
  strDescription: string;
  lDescription: TSERVICE_DESCRIPTION;

begin
   
        (省略)
  strDescription := 'test'; //ローカル変数に文字列を指定していますが実際は関数の引数より渡しています。
  lDescription.lpDescription := PChar(strDescription);
  ChangeServiceConfig2A(schService, SERVICE_CONFIG_DESCRIPTION, @lDescription);


take  URL  2019-10-29 17:15:33  No: 148352

外しているかも知れませんが
ChangeServiceConfig2Aの引数がポインタのポインタだからではないでしょうか?

lpDescription: string;
lpDescriptionptr: pstring;

と定義して

lpDescription := 'test';
lpDescriptionptr := @lpDescription[1];

で引数を渡すのに

@lpDescriptionptr を使って見てはいかがでしょうか?

参考にしたページ
http://www.delphigroups.info/2/4/326163.html


HFUKUSHI  2019-10-29 17:25:18  No: 148353

Delphi 2009以降の文字列はUnicode(UTF-16LE)ですので、ChangeServiceConfig2AではなくChangeServiceConfig2またはChangeServiceConfig2Wを呼び出してください。
# 't'になるのは、UTF-16(String=UnicodeString)で'test'はANSI(AnsiString)で見ると't'+#0+'e'+#0+'s'+#0+'t'+#0になるからでしょう


HFUKUSHI  2019-10-29 17:30:11  No: 148354

ちなみにこんなTServiceのヘルパを作って使ってます。参考まで。

unit UServiceHelper;

interface

uses
  Winapi.Windows, Winapi.WinSvc,
  System.SysUtils,
  Vcl.SvcMgr;

type
  TServiceHelper = class helper for TService
  public
    // Set service description (call this function in TService.AfterInstall event)
    procedure SetServiceDescription(const Description: String);
    // Set service failure actions
    procedure SetServiceFailureActions(const Actions: SERVICE_FAILURE_ACTIONS);
  end;

implementation

procedure TServiceHelper.SetServiceDescription(const Description: String);
var
  SvcMgr: SC_HANDLE;
  Svc: SC_HANDLE;
  ServiceDescr: SERVICE_DESCRIPTION;
begin

  { Open service control manager }
  SvcMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if SvcMgr = 0 then
  begin
    RaiseLastOSError;
  end;

  try
    { Open service }
    Svc := OpenService(SvcMgr,PChar(Self.Name),STANDARD_RIGHTS_REQUIRED or SERVICE_CHANGE_CONFIG);
    if Svc = 0 then
    begin
      RaiseLastOSError;
    end;

    try
      { Set service description }
      ServiceDescr.lpDescription := PChar(Description);
      if ChangeServiceConfig2(Svc,SERVICE_CONFIG_DESCRIPTION,@ServiceDescr) = False then
      begin
        RaiseLastOSError;
      end;

    finally
      { Close service handle }
      CloseServiceHandle(Svc);
    end;

  finally
    { Close service control manager handle }
    CloseServiceHandle(SvcMgr);
  end;

end;

procedure TServiceHelper.SetServiceFailureActions(const Actions: SERVICE_FAILURE_ACTIONS);
var
  SvcMgr: SC_HANDLE;
  Svc: SC_HANDLE;
  Access: DWORD;
  I: Integer;
  P: LPSC_ACTION;
begin

  Access := STANDARD_RIGHTS_REQUIRED or SERVICE_CHANGE_CONFIG;

  { Check actions }
  P := Actions.lpsaActions;
  if P <> nil then
  begin
    for I := 1 to Actions.cActions do  // FI:W528
    begin
      if P^.&Type = SC_ACTION_REBOOT then
      begin
        Access := Access or SERVICE_START;
      end;
      Inc(P);
    end;
  end;

  { Open service control manager }
  SvcMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if SvcMgr = 0 then
  begin
    RaiseLastOSError;
  end;

  try
    { Open service }
    Svc := OpenService(SvcMgr,PChar(Self.Name), Access);
    if Svc = 0 then
    begin
      RaiseLastOSError;
    end;

    try
      { Set service failure actions }
      if ChangeServiceConfig2(Svc,SERVICE_CONFIG_FAILURE_ACTIONS,@Actions) = False then
      begin
        RaiseLastOSError;
      end;

    finally
      { Close service handle }
      CloseServiceHandle(Svc);
    end;

  finally
    { Close service control manager handle }
    CloseServiceHandle(SvcMgr);
  end;

end;

end.


のぶ  2019-10-29 17:49:06  No: 148355

HFUKUSHIさんのおっしゃるとおりChangeServiceConfig2に変更したところ、うまくいきました。
大変ありがとうございます。文字コードについて勉強しないとだめですね。
TServiceのヘルパも参考になります。

takaさんの方法は試しておりませんが、
ご回答いただいて、うれしかったです。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加