Win32 API 日本語リファレンス
ホームSystem.Services › CreateServiceA

CreateServiceA

関数
新しいサービスを作成しSCMデータベースに登録する。
DLLADVAPI32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

// ADVAPI32.dll  (ANSI / -A)
#include <windows.h>

SC_HANDLE CreateServiceA(
    SC_HANDLE hSCManager,
    LPCSTR lpServiceName,
    LPCSTR lpDisplayName,   // optional
    DWORD dwDesiredAccess,
    ENUM_SERVICE_TYPE dwServiceType,
    SERVICE_START_TYPE dwStartType,
    SERVICE_ERROR dwErrorControl,
    LPCSTR lpBinaryPathName,   // optional
    LPCSTR lpLoadOrderGroup,   // optional
    DWORD* lpdwTagId,   // optional
    LPCSTR lpDependencies,   // optional
    LPCSTR lpServiceStartName,   // optional
    LPCSTR lpPassword   // optional
);

パラメーター

名前方向説明
hSCManagerSC_HANDLEinサービス制御マネージャーのデータベースへのハンドル。このハンドルは OpenSCManager 関数によって返され、SC_MANAGER_CREATE_SERVICE アクセス権を持っている必要があります。詳細については、 Service Security and Access Rights を参照してください。
lpServiceNameLPCSTRinインストールするサービスの名前。文字列の最大長は 256 文字です。サービス制御マネージャーのデータベースは文字の大文字小文字を保持しますが、サービス名の比較は常に大文字小文字を区別しません。スラッシュ (/) とバックスラッシュ (\) はサービス名として使用できません。
lpDisplayNameLPCSTRinoptionalサービスを識別するためにユーザーインターフェイスプログラムが使用する表示名。この文字列の最大長は 256 文字です。名前はサービス制御マネージャー内で大文字小文字が保持されます。表示名の比較は常に大文字小文字を区別しません。
dwDesiredAccessDWORDinサービスへのアクセス。要求されたアクセスを許可する前に、システムは呼び出し元プロセスのアクセストークンを確認します。値の一覧については、 Service Security and Access Rights を参照してください。
dwServiceTypeENUM_SERVICE_TYPEin

サービスの種類。このパラメーターには次のいずれかの値を指定できます。

Value Meaning
SERVICE_ADAPTER
0x00000004
予約済み。
SERVICE_FILE_SYSTEM_DRIVER
0x00000002
ファイルシステムドライバーサービス。
SERVICE_KERNEL_DRIVER
0x00000001
ドライバーサービス。
SERVICE_RECOGNIZER_DRIVER
0x00000008
予約済み。
SERVICE_WIN32_OWN_PROCESS
0x00000010
独自のプロセス内で実行されるサービス。
SERVICE_WIN32_SHARE_PROCESS
0x00000020
1 つ以上の他のサービスとプロセスを共有するサービス。詳細については、Service Programs を参照してください。

SERVICE_WIN32_OWN_PROCESS または SERVICE_WIN32_SHARE_PROCESS を指定し、かつサービスが LocalSystem アカウント のコンテキストで実行されている場合は、次の値も指定できます。

Value Meaning
SERVICE_INTERACTIVE_PROCESS
0x00000100
サービスがデスクトップと対話できます。

詳細については、 Interactive Services を参照してください。

dwStartTypeSERVICE_START_TYPEin

サービスの起動オプション。このパラメーターには次のいずれかの値を指定できます。

Value Meaning
SERVICE_AUTO_START
0x00000002
システム起動時にサービス制御マネージャーによって自動的に開始されるサービス。詳細については、Automatically Starting Services を参照してください。
SERVICE_BOOT_START
0x00000000
システムローダーによって開始されるデバイスドライバー。この値はドライバーサービスでのみ有効です。
SERVICE_DEMAND_START
0x00000003
プロセスが StartService 関数を呼び出したときに、サービス制御マネージャーによって開始されるサービス。詳細については、Starting Services on Demand を参照してください。
SERVICE_DISABLED
0x00000004
開始できないサービス。サービスを開始しようとすると、エラーコード ERROR_SERVICE_DISABLED が返されます。
SERVICE_SYSTEM_START
0x00000001
IoInitSystem 関数によって開始されるデバイスドライバー。この値はドライバーサービスでのみ有効です。
dwErrorControlSERVICE_ERRORin

このサービスの開始に失敗した場合のエラーの重大度、および実行される処理。このパラメーターには次のいずれかの値を指定できます。

Value Meaning
SERVICE_ERROR_CRITICAL
0x00000003
起動プログラムは可能であればイベントログにエラーを記録します。前回正常起動時の構成 (last-known-good) で起動中の場合、起動操作は失敗します。それ以外の場合は、前回正常起動時の構成でシステムが再起動されます。
SERVICE_ERROR_IGNORE
0x00000000
起動プログラムはエラーを無視して起動操作を続行します。
SERVICE_ERROR_NORMAL
0x00000001
起動プログラムはイベントログにエラーを記録しますが、起動操作を続行します。
SERVICE_ERROR_SEVERE
0x00000002
起動プログラムはイベントログにエラーを記録します。前回正常起動時の構成 (last-known-good) で起動中の場合、起動操作は続行されます。それ以外の場合は、前回正常起動時の構成でシステムが再起動されます。
lpBinaryPathNameLPCSTRinoptional

サービスのバイナリファイルへの完全修飾パス。パスにスペースが含まれる場合は、正しく解釈されるように引用符で囲む必要があります。たとえば、"d:\my share\myservice.exe" は ""d:\my share\myservice.exe"" と指定する必要があります。

パスには、自動開始サービス用の引数を含めることもできます。たとえば、"d:\myshare\myservice.exe arg1 arg2" のように指定します。これらの引数はサービスのエントリポイント (通常は main 関数) に渡されます。

別のコンピューター上のパスを指定する場合、リモート呼び出しで使用されるセキュリティコンテキストがローカルコンピューターのコンピューターアカウントであるため、その共有にローカルコンピューターのコンピューターアカウントからアクセスできる必要があります。ただし、この要件により、リモートコンピューターに潜在的な脆弱性があるとローカルコンピューターに影響が及ぶ可能性があります。したがって、ローカルファイルを使用することを推奨します。

lpLoadOrderGroupLPCSTRinoptional

このサービスが属するロード順序グループの名前。サービスがグループに属さない場合は NULL または空文字列を指定します。

起動プログラムは、他のグループとの相対的な指定順序でサービスのグループを読み込むために、ロード順序グループを使用します。ロード順序グループの一覧は、次のレジストリ値に格納されています。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder

lpdwTagIdDWORD*outoptional

lpLoadOrderGroup パラメーターで指定したグループ内で一意となるタグ値を受け取る変数へのポインター。既存のタグを変更しない場合は NULL を指定します。

ロード順序グループ内でのサービス起動順序を制御するために、次のレジストリ値にタグ順序ベクトルを指定してタグを使用できます。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\GroupOrderList

タグは、SERVICE_BOOT_START または SERVICE_SYSTEM_START 開始種別を持つドライバーサービスに対してのみ評価されます。

lpDependenciesLPCSTRinoptional

このサービスより前にシステムが開始する必要があるサービスまたはロード順序グループの名前を、NULL 区切りで列挙し二重に NULL で終端した配列へのポインター。サービスに依存関係がない場合は NULL または空文字列を指定します。グループへの依存とは、グループのすべてのメンバーを開始しようとした後にグループの少なくとも 1 つのメンバーが実行されていれば、このサービスを実行できることを意味します。

サービスとサービスグループは同じ名前空間を共有するため、グループ名はサービス名と区別できるように SC_GROUP_IDENTIFIER をプレフィックスとして付ける必要があります。

lpServiceStartNameLPCSTRinoptional

サービスを実行するアカウントの名前。サービスの種類が SERVICE_WIN32_OWN_PROCESS の場合は、DomainName\UserName の形式でアカウント名を指定します。サービスプロセスはこのユーザーとしてログオンします。アカウントが組み込みドメインに属する場合は、.\UserName と指定できます。

このパラメーターが NULL の場合、 CreateServiceLocalSystem アカウント を使用します。サービスの種類で SERVICE_INTERACTIVE_PROCESS を指定する場合、サービスは LocalSystem アカウントで実行する必要があります。

このパラメーターが NT AUTHORITY\LocalService の場合、 CreateServiceLocalService アカウント を使用します。パラメーターが NT AUTHORITY\NetworkService の場合、 CreateServiceNetworkService アカウント を使用します。

共有プロセスは任意のユーザーとして実行できます。

サービスの種類が SERVICE_KERNEL_DRIVER または SERVICE_FILE_SYSTEM_DRIVER の場合、この名前はシステムがデバイスドライバーを読み込むために使用するドライバーオブジェクト名です。ドライバーが I/O システムによって作成される既定のオブジェクト名を使用する場合は NULL を指定します。

サービスは、管理されたアカウント (マネージドアカウント) または仮想アカウントを使用するように構成できます。サービスがマネージドサービスアカウントを使用するように構成されている場合、この名前はマネージドサービスアカウント名になります。サービスが仮想アカウントを使用するように構成されている場合は、名前を NT SERVICE\ServiceName の形式で指定します。マネージドサービスアカウントと仮想アカウントの詳細については、Service Accounts Step-by-Step Guide を参照してください。

Windows Server 2008、Windows Vista、Windows Server 2003 および Windows XP: マネージドサービスアカウントと仮想アカウントは、Windows 7 および Windows Server 2008 R2 までサポートされていません。

lpPasswordLPCSTRinoptional

lpServiceStartName パラメーターで指定したアカウント名のパスワード。アカウントにパスワードがない場合、またはサービスが LocalService、NetworkService、もしくは LocalSystem アカウントで実行される場合は、空文字列を指定します。詳細については、 Service Record List を参照してください。

lpServiceStartName パラメーターで指定したアカウント名がマネージドサービスアカウントまたは仮想アカウントの名前である場合、lpPassword パラメーターは NULL でなければなりません。

ドライバーサービスではパスワードは無視されます。

戻り値の型: SC_HANDLE

公式ドキュメント

サービスオブジェクトを作成し、指定したサービス制御マネージャーのデータベースに追加します。(ANSI)

戻り値

関数が成功した場合、戻り値はサービスへのハンドルです。

関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには、 GetLastError を呼び出します。

次のエラーコードがサービス制御マネージャーによって設定される場合があります。その他のエラーコードは、サービス制御マネージャーが呼び出すレジストリ関数によって設定される場合があります。

Return code Description
ERROR_ACCESS_DENIED
SCM データベースへのハンドルに SC_MANAGER_CREATE_SERVICE アクセス権がありません。
ERROR_CIRCULAR_DEPENDENCY
循環するサービス依存関係が指定されました。
ERROR_DUPLICATE_SERVICE_NAME
指定した表示名が、サービス名または別の表示名として、サービス制御マネージャーのデータベースに既に存在します。
ERROR_INVALID_HANDLE
指定したサービス制御マネージャーのデータベースへのハンドルが無効です。
ERROR_INVALID_NAME
指定したサービス名が無効です。
ERROR_INVALID_PARAMETER
指定したパラメーターが無効です。
ERROR_INVALID_SERVICE_ACCOUNT
lpServiceStartName パラメーターで指定したユーザーアカウント名が存在しません。
ERROR_SERVICE_EXISTS
指定したサービスはこのデータベースに既に存在します。
ERROR_SERVICE_MARKED_FOR_DELETE
指定したサービスはこのデータベースに既に存在し、削除対象としてマークされています。

解説(Remarks)

CreateService 関数は、サービスオブジェクトを作成し、次のレジストリキーの下にサービスと同じ名前のキーを作成することで、サービス制御マネージャーのデータベースにインストールします。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services

CreateServiceChangeServiceConfig、および ChangeServiceConfig2 で指定された情報は、このキーの下に値として保存されます。サービスに対して保存される値の例を次に示します。

Value Description
DependOnGroup lpDependencies で指定された、このサービスが依存するロード順序グループ。
DependOnService lpDependencies で指定された、このサービスが依存するサービス。
Description ChangeServiceConfig2 で指定された説明。
DisplayName lpDisplayName で指定された表示名。
ErrorControl dwErrorControl で指定されたエラー制御。
FailureActions ChangeServiceConfig2 で指定された失敗時のアクション。
Group lpLoadOrderGroup で指定されたロード順序グループ。この値を設定すると DependOnService 値の設定が上書きされる場合があることに注意してください。
ImagePath lpBinaryPathName で指定されたバイナリファイルの名前。
ObjectName lpServiceStartName で指定されたアカウント名。
Start dwStartType で指定された、サービスを開始するタイミング。
Tag lpdwTagId で指定されたタグ識別子。
Type dwServiceType で指定されたサービスの種類。

セットアッププログラムやサービス自体は、サービス固有の情報のために追加のサブキーを作成できます。

返されるハンドルは、 CreateService を呼び出したプロセスでのみ有効です。このハンドルは CloseServiceHandle 関数を呼び出して閉じることができます。

プロセスを共有するサービスを作成する場合は、 ExitProcess のようなプロセス全体に影響を与える関数の呼び出しを避けてください。また、サービス DLL をアンロードしないでください。

例については、 Installing a Service を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// ADVAPI32.dll  (ANSI / -A)
#include <windows.h>

SC_HANDLE CreateServiceA(
    SC_HANDLE hSCManager,
    LPCSTR lpServiceName,
    LPCSTR lpDisplayName,   // optional
    DWORD dwDesiredAccess,
    ENUM_SERVICE_TYPE dwServiceType,
    SERVICE_START_TYPE dwStartType,
    SERVICE_ERROR dwErrorControl,
    LPCSTR lpBinaryPathName,   // optional
    LPCSTR lpLoadOrderGroup,   // optional
    DWORD* lpdwTagId,   // optional
    LPCSTR lpDependencies,   // optional
    LPCSTR lpServiceStartName,   // optional
    LPCSTR lpPassword   // optional
);
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern IntPtr CreateServiceA(
    IntPtr hSCManager,   // SC_HANDLE
    [MarshalAs(UnmanagedType.LPStr)] string lpServiceName,   // LPCSTR
    [MarshalAs(UnmanagedType.LPStr)] string lpDisplayName,   // LPCSTR optional
    uint dwDesiredAccess,   // DWORD
    uint dwServiceType,   // ENUM_SERVICE_TYPE
    uint dwStartType,   // SERVICE_START_TYPE
    uint dwErrorControl,   // SERVICE_ERROR
    [MarshalAs(UnmanagedType.LPStr)] string lpBinaryPathName,   // LPCSTR optional
    [MarshalAs(UnmanagedType.LPStr)] string lpLoadOrderGroup,   // LPCSTR optional
    IntPtr lpdwTagId,   // DWORD* optional, out
    [MarshalAs(UnmanagedType.LPStr)] string lpDependencies,   // LPCSTR optional
    [MarshalAs(UnmanagedType.LPStr)] string lpServiceStartName,   // LPCSTR optional
    [MarshalAs(UnmanagedType.LPStr)] string lpPassword   // LPCSTR optional
);
<DllImport("ADVAPI32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function CreateServiceA(
    hSCManager As IntPtr,   ' SC_HANDLE
    <MarshalAs(UnmanagedType.LPStr)> lpServiceName As String,   ' LPCSTR
    <MarshalAs(UnmanagedType.LPStr)> lpDisplayName As String,   ' LPCSTR optional
    dwDesiredAccess As UInteger,   ' DWORD
    dwServiceType As UInteger,   ' ENUM_SERVICE_TYPE
    dwStartType As UInteger,   ' SERVICE_START_TYPE
    dwErrorControl As UInteger,   ' SERVICE_ERROR
    <MarshalAs(UnmanagedType.LPStr)> lpBinaryPathName As String,   ' LPCSTR optional
    <MarshalAs(UnmanagedType.LPStr)> lpLoadOrderGroup As String,   ' LPCSTR optional
    lpdwTagId As IntPtr,   ' DWORD* optional, out
    <MarshalAs(UnmanagedType.LPStr)> lpDependencies As String,   ' LPCSTR optional
    <MarshalAs(UnmanagedType.LPStr)> lpServiceStartName As String,   ' LPCSTR optional
    <MarshalAs(UnmanagedType.LPStr)> lpPassword As String   ' LPCSTR optional
) As IntPtr
End Function
' hSCManager : SC_HANDLE
' lpServiceName : LPCSTR
' lpDisplayName : LPCSTR optional
' dwDesiredAccess : DWORD
' dwServiceType : ENUM_SERVICE_TYPE
' dwStartType : SERVICE_START_TYPE
' dwErrorControl : SERVICE_ERROR
' lpBinaryPathName : LPCSTR optional
' lpLoadOrderGroup : LPCSTR optional
' lpdwTagId : DWORD* optional, out
' lpDependencies : LPCSTR optional
' lpServiceStartName : LPCSTR optional
' lpPassword : LPCSTR optional
Declare PtrSafe Function CreateServiceA Lib "advapi32" ( _
    ByVal hSCManager As LongPtr, _
    ByVal lpServiceName As String, _
    ByVal lpDisplayName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwServiceType As Long, _
    ByVal dwStartType As Long, _
    ByVal dwErrorControl As Long, _
    ByVal lpBinaryPathName As String, _
    ByVal lpLoadOrderGroup As String, _
    ByVal lpdwTagId As LongPtr, _
    ByVal lpDependencies As String, _
    ByVal lpServiceStartName As String, _
    ByVal lpPassword As String) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

CreateServiceA = ctypes.windll.advapi32.CreateServiceA
CreateServiceA.restype = ctypes.c_void_p
CreateServiceA.argtypes = [
    wintypes.HANDLE,  # hSCManager : SC_HANDLE
    wintypes.LPCSTR,  # lpServiceName : LPCSTR
    wintypes.LPCSTR,  # lpDisplayName : LPCSTR optional
    wintypes.DWORD,  # dwDesiredAccess : DWORD
    wintypes.DWORD,  # dwServiceType : ENUM_SERVICE_TYPE
    wintypes.DWORD,  # dwStartType : SERVICE_START_TYPE
    wintypes.DWORD,  # dwErrorControl : SERVICE_ERROR
    wintypes.LPCSTR,  # lpBinaryPathName : LPCSTR optional
    wintypes.LPCSTR,  # lpLoadOrderGroup : LPCSTR optional
    ctypes.POINTER(wintypes.DWORD),  # lpdwTagId : DWORD* optional, out
    wintypes.LPCSTR,  # lpDependencies : LPCSTR optional
    wintypes.LPCSTR,  # lpServiceStartName : LPCSTR optional
    wintypes.LPCSTR,  # lpPassword : LPCSTR optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('ADVAPI32.dll')
CreateServiceA = Fiddle::Function.new(
  lib['CreateServiceA'],
  [
    Fiddle::TYPE_VOIDP,  # hSCManager : SC_HANDLE
    Fiddle::TYPE_VOIDP,  # lpServiceName : LPCSTR
    Fiddle::TYPE_VOIDP,  # lpDisplayName : LPCSTR optional
    -Fiddle::TYPE_INT,  # dwDesiredAccess : DWORD
    -Fiddle::TYPE_INT,  # dwServiceType : ENUM_SERVICE_TYPE
    -Fiddle::TYPE_INT,  # dwStartType : SERVICE_START_TYPE
    -Fiddle::TYPE_INT,  # dwErrorControl : SERVICE_ERROR
    Fiddle::TYPE_VOIDP,  # lpBinaryPathName : LPCSTR optional
    Fiddle::TYPE_VOIDP,  # lpLoadOrderGroup : LPCSTR optional
    Fiddle::TYPE_VOIDP,  # lpdwTagId : DWORD* optional, out
    Fiddle::TYPE_VOIDP,  # lpDependencies : LPCSTR optional
    Fiddle::TYPE_VOIDP,  # lpServiceStartName : LPCSTR optional
    Fiddle::TYPE_VOIDP,  # lpPassword : LPCSTR optional
  ],
  Fiddle::TYPE_VOIDP)
#[link(name = "advapi32")]
extern "system" {
    fn CreateServiceA(
        hSCManager: *mut core::ffi::c_void,  // SC_HANDLE
        lpServiceName: *const u8,  // LPCSTR
        lpDisplayName: *const u8,  // LPCSTR optional
        dwDesiredAccess: u32,  // DWORD
        dwServiceType: u32,  // ENUM_SERVICE_TYPE
        dwStartType: u32,  // SERVICE_START_TYPE
        dwErrorControl: u32,  // SERVICE_ERROR
        lpBinaryPathName: *const u8,  // LPCSTR optional
        lpLoadOrderGroup: *const u8,  // LPCSTR optional
        lpdwTagId: *mut u32,  // DWORD* optional, out
        lpDependencies: *const u8,  // LPCSTR optional
        lpServiceStartName: *const u8,  // LPCSTR optional
        lpPassword: *const u8  // LPCSTR optional
    ) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateServiceA(IntPtr hSCManager, [MarshalAs(UnmanagedType.LPStr)] string lpServiceName, [MarshalAs(UnmanagedType.LPStr)] string lpDisplayName, uint dwDesiredAccess, uint dwServiceType, uint dwStartType, uint dwErrorControl, [MarshalAs(UnmanagedType.LPStr)] string lpBinaryPathName, [MarshalAs(UnmanagedType.LPStr)] string lpLoadOrderGroup, IntPtr lpdwTagId, [MarshalAs(UnmanagedType.LPStr)] string lpDependencies, [MarshalAs(UnmanagedType.LPStr)] string lpServiceStartName, [MarshalAs(UnmanagedType.LPStr)] string lpPassword);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_CreateServiceA' -Namespace Win32 -PassThru
# $api::CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
#uselib "ADVAPI32.dll"
#func global CreateServiceA "CreateServiceA" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; CreateServiceA hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, varptr(lpdwTagId), lpDependencies, lpServiceStartName, lpPassword   ; 戻り値は stat
; hSCManager : SC_HANDLE -> "sptr"
; lpServiceName : LPCSTR -> "sptr"
; lpDisplayName : LPCSTR optional -> "sptr"
; dwDesiredAccess : DWORD -> "sptr"
; dwServiceType : ENUM_SERVICE_TYPE -> "sptr"
; dwStartType : SERVICE_START_TYPE -> "sptr"
; dwErrorControl : SERVICE_ERROR -> "sptr"
; lpBinaryPathName : LPCSTR optional -> "sptr"
; lpLoadOrderGroup : LPCSTR optional -> "sptr"
; lpdwTagId : DWORD* optional, out -> "sptr"
; lpDependencies : LPCSTR optional -> "sptr"
; lpServiceStartName : LPCSTR optional -> "sptr"
; lpPassword : LPCSTR optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "ADVAPI32.dll"
#cfunc global CreateServiceA "CreateServiceA" sptr, str, str, int, int, int, int, str, str, var, str, str, str
; res = CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
; hSCManager : SC_HANDLE -> "sptr"
; lpServiceName : LPCSTR -> "str"
; lpDisplayName : LPCSTR optional -> "str"
; dwDesiredAccess : DWORD -> "int"
; dwServiceType : ENUM_SERVICE_TYPE -> "int"
; dwStartType : SERVICE_START_TYPE -> "int"
; dwErrorControl : SERVICE_ERROR -> "int"
; lpBinaryPathName : LPCSTR optional -> "str"
; lpLoadOrderGroup : LPCSTR optional -> "str"
; lpdwTagId : DWORD* optional, out -> "var"
; lpDependencies : LPCSTR optional -> "str"
; lpServiceStartName : LPCSTR optional -> "str"
; lpPassword : LPCSTR optional -> "str"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; SC_HANDLE CreateServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, LPCSTR lpDisplayName, DWORD dwDesiredAccess, ENUM_SERVICE_TYPE dwServiceType, SERVICE_START_TYPE dwStartType, SERVICE_ERROR dwErrorControl, LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, DWORD* lpdwTagId, LPCSTR lpDependencies, LPCSTR lpServiceStartName, LPCSTR lpPassword)
#uselib "ADVAPI32.dll"
#cfunc global CreateServiceA "CreateServiceA" intptr, str, str, int, int, int, int, str, str, var, str, str, str
; res = CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
; hSCManager : SC_HANDLE -> "intptr"
; lpServiceName : LPCSTR -> "str"
; lpDisplayName : LPCSTR optional -> "str"
; dwDesiredAccess : DWORD -> "int"
; dwServiceType : ENUM_SERVICE_TYPE -> "int"
; dwStartType : SERVICE_START_TYPE -> "int"
; dwErrorControl : SERVICE_ERROR -> "int"
; lpBinaryPathName : LPCSTR optional -> "str"
; lpLoadOrderGroup : LPCSTR optional -> "str"
; lpdwTagId : DWORD* optional, out -> "var"
; lpDependencies : LPCSTR optional -> "str"
; lpServiceStartName : LPCSTR optional -> "str"
; lpPassword : LPCSTR optional -> "str"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
	procCreateServiceA = advapi32.NewProc("CreateServiceA")
)

// hSCManager (SC_HANDLE), lpServiceName (LPCSTR), lpDisplayName (LPCSTR optional), dwDesiredAccess (DWORD), dwServiceType (ENUM_SERVICE_TYPE), dwStartType (SERVICE_START_TYPE), dwErrorControl (SERVICE_ERROR), lpBinaryPathName (LPCSTR optional), lpLoadOrderGroup (LPCSTR optional), lpdwTagId (DWORD* optional, out), lpDependencies (LPCSTR optional), lpServiceStartName (LPCSTR optional), lpPassword (LPCSTR optional)
r1, _, err := procCreateServiceA.Call(
	uintptr(hSCManager),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpServiceName))),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpDisplayName))),
	uintptr(dwDesiredAccess),
	uintptr(dwServiceType),
	uintptr(dwStartType),
	uintptr(dwErrorControl),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpBinaryPathName))),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpLoadOrderGroup))),
	uintptr(lpdwTagId),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpDependencies))),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpServiceStartName))),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpPassword))),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // SC_HANDLE
function CreateServiceA(
  hSCManager: THandle;   // SC_HANDLE
  lpServiceName: PAnsiChar;   // LPCSTR
  lpDisplayName: PAnsiChar;   // LPCSTR optional
  dwDesiredAccess: DWORD;   // DWORD
  dwServiceType: DWORD;   // ENUM_SERVICE_TYPE
  dwStartType: DWORD;   // SERVICE_START_TYPE
  dwErrorControl: DWORD;   // SERVICE_ERROR
  lpBinaryPathName: PAnsiChar;   // LPCSTR optional
  lpLoadOrderGroup: PAnsiChar;   // LPCSTR optional
  lpdwTagId: Pointer;   // DWORD* optional, out
  lpDependencies: PAnsiChar;   // LPCSTR optional
  lpServiceStartName: PAnsiChar;   // LPCSTR optional
  lpPassword: PAnsiChar   // LPCSTR optional
): THandle; stdcall;
  external 'ADVAPI32.dll' name 'CreateServiceA';
result := DllCall("ADVAPI32\CreateServiceA"
    , "Ptr", hSCManager   ; SC_HANDLE
    , "AStr", lpServiceName   ; LPCSTR
    , "AStr", lpDisplayName   ; LPCSTR optional
    , "UInt", dwDesiredAccess   ; DWORD
    , "UInt", dwServiceType   ; ENUM_SERVICE_TYPE
    , "UInt", dwStartType   ; SERVICE_START_TYPE
    , "UInt", dwErrorControl   ; SERVICE_ERROR
    , "AStr", lpBinaryPathName   ; LPCSTR optional
    , "AStr", lpLoadOrderGroup   ; LPCSTR optional
    , "Ptr", lpdwTagId   ; DWORD* optional, out
    , "AStr", lpDependencies   ; LPCSTR optional
    , "AStr", lpServiceStartName   ; LPCSTR optional
    , "AStr", lpPassword   ; LPCSTR optional
    , "Ptr")   ; return: SC_HANDLE
●CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword) = DLL("ADVAPI32.dll", "void* CreateServiceA(void*, char*, char*, dword, dword, dword, dword, char*, char*, void*, char*, char*, char*)")
# 呼び出し: CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
# hSCManager : SC_HANDLE -> "void*"
# lpServiceName : LPCSTR -> "char*"
# lpDisplayName : LPCSTR optional -> "char*"
# dwDesiredAccess : DWORD -> "dword"
# dwServiceType : ENUM_SERVICE_TYPE -> "dword"
# dwStartType : SERVICE_START_TYPE -> "dword"
# dwErrorControl : SERVICE_ERROR -> "dword"
# lpBinaryPathName : LPCSTR optional -> "char*"
# lpLoadOrderGroup : LPCSTR optional -> "char*"
# lpdwTagId : DWORD* optional, out -> "void*"
# lpDependencies : LPCSTR optional -> "char*"
# lpServiceStartName : LPCSTR optional -> "char*"
# lpPassword : LPCSTR optional -> "char*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "advapi32" fn CreateServiceA(
    hSCManager: ?*anyopaque, // SC_HANDLE
    lpServiceName: [*c]const u8, // LPCSTR
    lpDisplayName: [*c]const u8, // LPCSTR optional
    dwDesiredAccess: u32, // DWORD
    dwServiceType: u32, // ENUM_SERVICE_TYPE
    dwStartType: u32, // SERVICE_START_TYPE
    dwErrorControl: u32, // SERVICE_ERROR
    lpBinaryPathName: [*c]const u8, // LPCSTR optional
    lpLoadOrderGroup: [*c]const u8, // LPCSTR optional
    lpdwTagId: [*c]u32, // DWORD* optional, out
    lpDependencies: [*c]const u8, // LPCSTR optional
    lpServiceStartName: [*c]const u8, // LPCSTR optional
    lpPassword: [*c]const u8 // LPCSTR optional
) callconv(std.os.windows.WINAPI) ?*anyopaque;
proc CreateServiceA(
    hSCManager: pointer,  # SC_HANDLE
    lpServiceName: cstring,  # LPCSTR
    lpDisplayName: cstring,  # LPCSTR optional
    dwDesiredAccess: uint32,  # DWORD
    dwServiceType: uint32,  # ENUM_SERVICE_TYPE
    dwStartType: uint32,  # SERVICE_START_TYPE
    dwErrorControl: uint32,  # SERVICE_ERROR
    lpBinaryPathName: cstring,  # LPCSTR optional
    lpLoadOrderGroup: cstring,  # LPCSTR optional
    lpdwTagId: ptr uint32,  # DWORD* optional, out
    lpDependencies: cstring,  # LPCSTR optional
    lpServiceStartName: cstring,  # LPCSTR optional
    lpPassword: cstring  # LPCSTR optional
): pointer {.importc: "CreateServiceA", stdcall, dynlib: "ADVAPI32.dll".}
pragma(lib, "advapi32");
extern(Windows)
void* CreateServiceA(
    void* hSCManager,   // SC_HANDLE
    const(char)* lpServiceName,   // LPCSTR
    const(char)* lpDisplayName,   // LPCSTR optional
    uint dwDesiredAccess,   // DWORD
    uint dwServiceType,   // ENUM_SERVICE_TYPE
    uint dwStartType,   // SERVICE_START_TYPE
    uint dwErrorControl,   // SERVICE_ERROR
    const(char)* lpBinaryPathName,   // LPCSTR optional
    const(char)* lpLoadOrderGroup,   // LPCSTR optional
    uint* lpdwTagId,   // DWORD* optional, out
    const(char)* lpDependencies,   // LPCSTR optional
    const(char)* lpServiceStartName,   // LPCSTR optional
    const(char)* lpPassword   // LPCSTR optional
);
ccall((:CreateServiceA, "ADVAPI32.dll"), stdcall, Ptr{Cvoid},
      (Ptr{Cvoid}, Cstring, Cstring, UInt32, UInt32, UInt32, UInt32, Cstring, Cstring, Ptr{UInt32}, Cstring, Cstring, Cstring),
      hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
# hSCManager : SC_HANDLE -> Ptr{Cvoid}
# lpServiceName : LPCSTR -> Cstring
# lpDisplayName : LPCSTR optional -> Cstring
# dwDesiredAccess : DWORD -> UInt32
# dwServiceType : ENUM_SERVICE_TYPE -> UInt32
# dwStartType : SERVICE_START_TYPE -> UInt32
# dwErrorControl : SERVICE_ERROR -> UInt32
# lpBinaryPathName : LPCSTR optional -> Cstring
# lpLoadOrderGroup : LPCSTR optional -> Cstring
# lpdwTagId : DWORD* optional, out -> Ptr{UInt32}
# lpDependencies : LPCSTR optional -> Cstring
# lpServiceStartName : LPCSTR optional -> Cstring
# lpPassword : LPCSTR optional -> Cstring
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
void* CreateServiceA(
    void* hSCManager,
    const char* lpServiceName,
    const char* lpDisplayName,
    uint32_t dwDesiredAccess,
    uint32_t dwServiceType,
    uint32_t dwStartType,
    uint32_t dwErrorControl,
    const char* lpBinaryPathName,
    const char* lpLoadOrderGroup,
    uint32_t* lpdwTagId,
    const char* lpDependencies,
    const char* lpServiceStartName,
    const char* lpPassword);
]]
local advapi32 = ffi.load("advapi32")
-- advapi32.CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
-- hSCManager : SC_HANDLE
-- lpServiceName : LPCSTR
-- lpDisplayName : LPCSTR optional
-- dwDesiredAccess : DWORD
-- dwServiceType : ENUM_SERVICE_TYPE
-- dwStartType : SERVICE_START_TYPE
-- dwErrorControl : SERVICE_ERROR
-- lpBinaryPathName : LPCSTR optional
-- lpLoadOrderGroup : LPCSTR optional
-- lpdwTagId : DWORD* optional, out
-- lpDependencies : LPCSTR optional
-- lpServiceStartName : LPCSTR optional
-- lpPassword : LPCSTR optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('ADVAPI32.dll');
const CreateServiceA = lib.func('__stdcall', 'CreateServiceA', 'void *', ['void *', 'str', 'str', 'uint32_t', 'uint32_t', 'uint32_t', 'uint32_t', 'str', 'str', 'uint32_t *', 'str', 'str', 'str']);
// CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
// hSCManager : SC_HANDLE -> 'void *'
// lpServiceName : LPCSTR -> 'str'
// lpDisplayName : LPCSTR optional -> 'str'
// dwDesiredAccess : DWORD -> 'uint32_t'
// dwServiceType : ENUM_SERVICE_TYPE -> 'uint32_t'
// dwStartType : SERVICE_START_TYPE -> 'uint32_t'
// dwErrorControl : SERVICE_ERROR -> 'uint32_t'
// lpBinaryPathName : LPCSTR optional -> 'str'
// lpLoadOrderGroup : LPCSTR optional -> 'str'
// lpdwTagId : DWORD* optional, out -> 'uint32_t *'
// lpDependencies : LPCSTR optional -> 'str'
// lpServiceStartName : LPCSTR optional -> 'str'
// lpPassword : LPCSTR optional -> 'str'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("ADVAPI32.dll", {
  CreateServiceA: { parameters: ["pointer", "buffer", "buffer", "u32", "u32", "u32", "u32", "buffer", "buffer", "pointer", "buffer", "buffer", "buffer"], result: "pointer" },
});
// lib.symbols.CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword)
// hSCManager : SC_HANDLE -> "pointer"
// lpServiceName : LPCSTR -> "buffer"
// lpDisplayName : LPCSTR optional -> "buffer"
// dwDesiredAccess : DWORD -> "u32"
// dwServiceType : ENUM_SERVICE_TYPE -> "u32"
// dwStartType : SERVICE_START_TYPE -> "u32"
// dwErrorControl : SERVICE_ERROR -> "u32"
// lpBinaryPathName : LPCSTR optional -> "buffer"
// lpLoadOrderGroup : LPCSTR optional -> "buffer"
// lpdwTagId : DWORD* optional, out -> "pointer"
// lpDependencies : LPCSTR optional -> "buffer"
// lpServiceStartName : LPCSTR optional -> "buffer"
// lpPassword : LPCSTR optional -> "buffer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
void* CreateServiceA(
    void* hSCManager,
    const char* lpServiceName,
    const char* lpDisplayName,
    uint32_t dwDesiredAccess,
    uint32_t dwServiceType,
    uint32_t dwStartType,
    uint32_t dwErrorControl,
    const char* lpBinaryPathName,
    const char* lpLoadOrderGroup,
    uint32_t* lpdwTagId,
    const char* lpDependencies,
    const char* lpServiceStartName,
    const char* lpPassword);
C, "ADVAPI32.dll");
// $ffi->CreateServiceA(hSCManager, lpServiceName, lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId, lpDependencies, lpServiceStartName, lpPassword);
// hSCManager : SC_HANDLE
// lpServiceName : LPCSTR
// lpDisplayName : LPCSTR optional
// dwDesiredAccess : DWORD
// dwServiceType : ENUM_SERVICE_TYPE
// dwStartType : SERVICE_START_TYPE
// dwErrorControl : SERVICE_ERROR
// lpBinaryPathName : LPCSTR optional
// lpLoadOrderGroup : LPCSTR optional
// lpdwTagId : DWORD* optional, out
// lpDependencies : LPCSTR optional
// lpServiceStartName : LPCSTR optional
// lpPassword : LPCSTR optional
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Advapi32 extends StdCallLibrary {
    Advapi32 INSTANCE = Native.load("advapi32", Advapi32.class, W32APIOptions.ASCII_OPTIONS);
    Pointer CreateServiceA(
        Pointer hSCManager,   // SC_HANDLE
        String lpServiceName,   // LPCSTR
        String lpDisplayName,   // LPCSTR optional
        int dwDesiredAccess,   // DWORD
        int dwServiceType,   // ENUM_SERVICE_TYPE
        int dwStartType,   // SERVICE_START_TYPE
        int dwErrorControl,   // SERVICE_ERROR
        String lpBinaryPathName,   // LPCSTR optional
        String lpLoadOrderGroup,   // LPCSTR optional
        IntByReference lpdwTagId,   // DWORD* optional, out
        String lpDependencies,   // LPCSTR optional
        String lpServiceStartName,   // LPCSTR optional
        String lpPassword   // LPCSTR optional
    );
}
@[Link("advapi32")]
lib LibADVAPI32
  fun CreateServiceA = CreateServiceA(
    hSCManager : Void*,   # SC_HANDLE
    lpServiceName : UInt8*,   # LPCSTR
    lpDisplayName : UInt8*,   # LPCSTR optional
    dwDesiredAccess : UInt32,   # DWORD
    dwServiceType : UInt32,   # ENUM_SERVICE_TYPE
    dwStartType : UInt32,   # SERVICE_START_TYPE
    dwErrorControl : UInt32,   # SERVICE_ERROR
    lpBinaryPathName : UInt8*,   # LPCSTR optional
    lpLoadOrderGroup : UInt8*,   # LPCSTR optional
    lpdwTagId : UInt32*,   # DWORD* optional, out
    lpDependencies : UInt8*,   # LPCSTR optional
    lpServiceStartName : UInt8*,   # LPCSTR optional
    lpPassword : UInt8*   # LPCSTR optional
  ) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef CreateServiceANative = Pointer<Void> Function(Pointer<Void>, Pointer<Utf8>, Pointer<Utf8>, Uint32, Uint32, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Uint32>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
typedef CreateServiceADart = Pointer<Void> Function(Pointer<Void>, Pointer<Utf8>, Pointer<Utf8>, int, int, int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Uint32>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
final CreateServiceA = DynamicLibrary.open('ADVAPI32.dll')
    .lookupFunction<CreateServiceANative, CreateServiceADart>('CreateServiceA');
// hSCManager : SC_HANDLE -> Pointer<Void>
// lpServiceName : LPCSTR -> Pointer<Utf8>
// lpDisplayName : LPCSTR optional -> Pointer<Utf8>
// dwDesiredAccess : DWORD -> Uint32
// dwServiceType : ENUM_SERVICE_TYPE -> Uint32
// dwStartType : SERVICE_START_TYPE -> Uint32
// dwErrorControl : SERVICE_ERROR -> Uint32
// lpBinaryPathName : LPCSTR optional -> Pointer<Utf8>
// lpLoadOrderGroup : LPCSTR optional -> Pointer<Utf8>
// lpdwTagId : DWORD* optional, out -> Pointer<Uint32>
// lpDependencies : LPCSTR optional -> Pointer<Utf8>
// lpServiceStartName : LPCSTR optional -> Pointer<Utf8>
// lpPassword : LPCSTR optional -> Pointer<Utf8>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function CreateServiceA(
  hSCManager: THandle;   // SC_HANDLE
  lpServiceName: PAnsiChar;   // LPCSTR
  lpDisplayName: PAnsiChar;   // LPCSTR optional
  dwDesiredAccess: DWORD;   // DWORD
  dwServiceType: DWORD;   // ENUM_SERVICE_TYPE
  dwStartType: DWORD;   // SERVICE_START_TYPE
  dwErrorControl: DWORD;   // SERVICE_ERROR
  lpBinaryPathName: PAnsiChar;   // LPCSTR optional
  lpLoadOrderGroup: PAnsiChar;   // LPCSTR optional
  lpdwTagId: Pointer;   // DWORD* optional, out
  lpDependencies: PAnsiChar;   // LPCSTR optional
  lpServiceStartName: PAnsiChar;   // LPCSTR optional
  lpPassword: PAnsiChar   // LPCSTR optional
): THandle; stdcall;
  external 'ADVAPI32.dll' name 'CreateServiceA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "CreateServiceA"
  c_CreateServiceA :: Ptr () -> CString -> CString -> Word32 -> Word32 -> Word32 -> Word32 -> CString -> CString -> Ptr Word32 -> CString -> CString -> CString -> IO (Ptr ())
-- hSCManager : SC_HANDLE -> Ptr ()
-- lpServiceName : LPCSTR -> CString
-- lpDisplayName : LPCSTR optional -> CString
-- dwDesiredAccess : DWORD -> Word32
-- dwServiceType : ENUM_SERVICE_TYPE -> Word32
-- dwStartType : SERVICE_START_TYPE -> Word32
-- dwErrorControl : SERVICE_ERROR -> Word32
-- lpBinaryPathName : LPCSTR optional -> CString
-- lpLoadOrderGroup : LPCSTR optional -> CString
-- lpdwTagId : DWORD* optional, out -> Ptr Word32
-- lpDependencies : LPCSTR optional -> CString
-- lpServiceStartName : LPCSTR optional -> CString
-- lpPassword : LPCSTR optional -> CString
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let createservicea =
  foreign "CreateServiceA"
    ((ptr void) @-> string @-> string @-> uint32_t @-> uint32_t @-> uint32_t @-> uint32_t @-> string @-> string @-> (ptr uint32_t) @-> string @-> string @-> string @-> returning (ptr void))
(* hSCManager : SC_HANDLE -> (ptr void) *)
(* lpServiceName : LPCSTR -> string *)
(* lpDisplayName : LPCSTR optional -> string *)
(* dwDesiredAccess : DWORD -> uint32_t *)
(* dwServiceType : ENUM_SERVICE_TYPE -> uint32_t *)
(* dwStartType : SERVICE_START_TYPE -> uint32_t *)
(* dwErrorControl : SERVICE_ERROR -> uint32_t *)
(* lpBinaryPathName : LPCSTR optional -> string *)
(* lpLoadOrderGroup : LPCSTR optional -> string *)
(* lpdwTagId : DWORD* optional, out -> (ptr uint32_t) *)
(* lpDependencies : LPCSTR optional -> string *)
(* lpServiceStartName : LPCSTR optional -> string *)
(* lpPassword : LPCSTR optional -> string *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)

(cffi:defcfun ("CreateServiceA" create-service-a :convention :stdcall) :pointer
  (h-scmanager :pointer)   ; SC_HANDLE
  (lp-service-name :string)   ; LPCSTR
  (lp-display-name :string)   ; LPCSTR optional
  (dw-desired-access :uint32)   ; DWORD
  (dw-service-type :uint32)   ; ENUM_SERVICE_TYPE
  (dw-start-type :uint32)   ; SERVICE_START_TYPE
  (dw-error-control :uint32)   ; SERVICE_ERROR
  (lp-binary-path-name :string)   ; LPCSTR optional
  (lp-load-order-group :string)   ; LPCSTR optional
  (lpdw-tag-id :pointer)   ; DWORD* optional, out
  (lp-dependencies :string)   ; LPCSTR optional
  (lp-service-start-name :string)   ; LPCSTR optional
  (lp-password :string))   ; LPCSTR optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $CreateServiceA = Win32::API::More->new('ADVAPI32',
    'HANDLE CreateServiceA(HANDLE hSCManager, LPCSTR lpServiceName, LPCSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, LPVOID lpdwTagId, LPCSTR lpDependencies, LPCSTR lpServiceStartName, LPCSTR lpPassword)');
# my $ret = $CreateServiceA->Call($hSCManager, $lpServiceName, $lpDisplayName, $dwDesiredAccess, $dwServiceType, $dwStartType, $dwErrorControl, $lpBinaryPathName, $lpLoadOrderGroup, $lpdwTagId, $lpDependencies, $lpServiceStartName, $lpPassword);
# hSCManager : SC_HANDLE -> HANDLE
# lpServiceName : LPCSTR -> LPCSTR
# lpDisplayName : LPCSTR optional -> LPCSTR
# dwDesiredAccess : DWORD -> DWORD
# dwServiceType : ENUM_SERVICE_TYPE -> DWORD
# dwStartType : SERVICE_START_TYPE -> DWORD
# dwErrorControl : SERVICE_ERROR -> DWORD
# lpBinaryPathName : LPCSTR optional -> LPCSTR
# lpLoadOrderGroup : LPCSTR optional -> LPCSTR
# lpdwTagId : DWORD* optional, out -> LPVOID
# lpDependencies : LPCSTR optional -> LPCSTR
# lpServiceStartName : LPCSTR optional -> LPCSTR
# lpPassword : LPCSTR optional -> LPCSTR
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
公式の関連項目
使用する型