or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

automation.mdclient-api.mdcore-com.mdindex.mdserver.mdutilities.md

server.mddocs/

0

# Server Development

1

2

Framework for implementing COM servers in Python, including class factories, object registration, connection point support for events, and both in-process and local server architectures.

3

4

## Capabilities

5

6

### Base Server Classes

7

8

Foundation classes for implementing COM objects and coclasses with proper COM lifetime management.

9

10

```python { .api }

11

class COMObject:

12

"""Base class for implementing COM objects in Python."""

13

14

def __init__(self):

15

"""Initialize COM object with reference counting."""

16

17

def QueryInterface(self, interface):

18

"""

19

Query for interface implementation.

20

21

Args:

22

interface (type): Interface class to query for

23

24

Returns:

25

Interface implementation or None

26

"""

27

28

def AddRef(self):

29

"""

30

Increment reference count.

31

32

Returns:

33

int: New reference count

34

"""

35

36

def Release(self):

37

"""

38

Decrement reference count.

39

40

Returns:

41

int: New reference count (0 if object destroyed)

42

"""

43

44

class CoClass(COMObject):

45

"""Base class for COM coclasses with metaclass support."""

46

47

_reg_clsid_: str # Class identifier for registration

48

_reg_progid_: str # Programmatic identifier

49

_reg_desc_: str # Description for registry

50

_reg_clsctx_: int # Class context flags

51

52

def __init__(self):

53

"""Initialize coclass with proper COM semantics."""

54

```

55

56

### Class Factory

57

58

Standard COM class factory interface for creating object instances.

59

60

```python { .api }

61

class IClassFactory(IUnknown):

62

"""Standard interface for creating COM object instances."""

63

64

def CreateInstance(self, outer, interface):

65

"""

66

Create new instance of COM object.

67

68

Args:

69

outer (IUnknown, optional): Outer object for aggregation

70

interface (type): Interface to query for on new instance

71

72

Returns:

73

New COM object instance

74

75

Raises:

76

COMError: If creation fails or aggregation not supported

77

"""

78

79

def LockServer(self, lock):

80

"""

81

Lock server in memory to prevent unloading.

82

83

Args:

84

lock (bool): True to lock, False to unlock

85

"""

86

```

87

88

### Object Registration

89

90

Functions for registering COM objects in the Running Object Table and with the system.

91

92

```python { .api }

93

def RegisterActiveObject(comobj, weak=True):

94

"""

95

Register COM object as active for client access.

96

97

Args:

98

comobj: COM object instance to register

99

weak (bool): Use weak reference to allow object cleanup

100

101

Returns:

102

int: Registration token for later revocation

103

"""

104

105

def RevokeActiveObject(token):

106

"""

107

Remove object from Running Object Table.

108

109

Args:

110

token (int): Registration token from RegisterActiveObject

111

"""

112

```

113

114

### Server Types

115

116

Different server implementation patterns supported by comtypes.

117

118

#### In-Process Server

119

120

```python { .api }

121

# From comtypes.server.inprocserver module

122

123

def DllCanUnloadNow():

124

"""

125

Determine if DLL can be unloaded.

126

127

Returns:

128

HRESULT: S_OK if can unload, S_FALSE if still in use

129

"""

130

131

def DllGetClassObject(clsid, iid):

132

"""

133

Get class factory for specified class.

134

135

Args:

136

clsid (GUID): Class identifier

137

iid (GUID): Interface identifier (usually IClassFactory)

138

139

Returns:

140

Class factory instance

141

"""

142

143

# Note: DllRegisterServer and DllUnregisterServer are not implemented

144

# in comtypes. These functions would need to be implemented by the

145

# application developer for COM server registration.

146

```

147

148

#### Local Server

149

150

```python { .api }

151

# From comtypes.server.localserver module

152

153

class LocalServer:

154

"""Framework for implementing local (out-of-process) COM servers."""

155

156

def run(self, classobjects):

157

"""

158

Start local server with registered class objects.

159

160

Args:

161

classobjects (dict): Mapping of CLSIDs to class factory objects

162

"""

163

164

def run_sta(self):

165

"""Run server in single-threaded apartment mode."""

166

167

def run_mta(self):

168

"""Run server in multi-threaded apartment mode."""

169

170

def Lock(self):

171

"""Increment server lock count."""

172

173

def Unlock(self):

174

"""Decrement server lock count."""

175

```

176

177

### Connection Points

178

179

Support for COM events and callbacks through connection point interfaces.

180

181

```python { .api }

182

class IConnectionPointContainer(IUnknown):

183

"""Container interface for managing connection points."""

184

185

def EnumConnectionPoints(self):

186

"""

187

Get enumerator for all connection points.

188

189

Returns:

190

IEnumConnectionPoints: Connection point enumerator

191

"""

192

193

def FindConnectionPoint(self, iid):

194

"""

195

Find connection point for specific interface.

196

197

Args:

198

iid (GUID): Event interface identifier

199

200

Returns:

201

IConnectionPoint: Connection point for interface

202

"""

203

204

class IConnectionPoint(IUnknown):

205

"""Individual connection point for specific event interface."""

206

207

def GetConnectionInterface(self):

208

"""

209

Get interface ID for this connection point.

210

211

Returns:

212

GUID: Event interface identifier

213

"""

214

215

def GetConnectionPointContainer(self):

216

"""

217

Get parent connection point container.

218

219

Returns:

220

IConnectionPointContainer: Parent container

221

"""

222

223

def Advise(self, sink):

224

"""

225

Connect event sink to receive events.

226

227

Args:

228

sink: Object implementing event interface

229

230

Returns:

231

int: Connection cookie for later disconnection

232

"""

233

234

def Unadvise(self, cookie):

235

"""

236

Disconnect event sink.

237

238

Args:

239

cookie (int): Connection cookie from Advise

240

"""

241

242

def EnumConnections(self):

243

"""

244

Get enumerator for active connections.

245

246

Returns:

247

IEnumConnections: Active connection enumerator

248

"""

249

```

250

251

### Registration Utilities

252

253

Helper functions for COM server registration and unregistration.

254

255

```python { .api }

256

# From comtypes.server.register module

257

258

def register(cls):

259

"""

260

Register COM class in system registry.

261

262

Args:

263

cls (type): CoClass to register (must have registration attributes)

264

"""

265

266

def unregister(cls):

267

"""

268

Remove COM class from system registry.

269

270

Args:

271

cls (type): CoClass to unregister

272

"""

273

```

274

275

## Usage Examples

276

277

### Basic COM Object Implementation

278

279

```python

280

import comtypes

281

from comtypes.server import COMObject

282

283

class MyComObject(COMObject):

284

"""Simple COM object implementation."""

285

286

# Define supported interfaces

287

_com_interfaces_ = [comtypes.IUnknown]

288

289

def __init__(self):

290

super().__init__()

291

print("COM object created")

292

293

def my_method(self):

294

"""Custom method implementation."""

295

return "Hello from COM object"

296

297

# Create and use object

298

obj = MyComObject()

299

result = obj.my_method()

300

print(result)

301

```

302

303

### CoClass with Registration

304

305

```python

306

import comtypes

307

from comtypes.server import CoClass

308

from comtypes.GUID import GUID

309

310

# Define custom interface

311

class IMyInterface(comtypes.IUnknown):

312

_iid_ = GUID("{12345678-1234-5678-9ABC-123456789ABC}")

313

_methods_ = [

314

comtypes.STDMETHOD(comtypes.HRESULT, "DoSomething",

315

(['in'], comtypes.c_int, "value"))

316

]

317

318

class MyCoClass(CoClass):

319

"""COM coclass with registration information."""

320

321

# Registration metadata

322

_reg_clsid_ = "{87654321-4321-8765-CBA9-987654321CBA}"

323

_reg_progid_ = "MyApp.MyCoClass.1"

324

_reg_desc_ = "My COM CoClass"

325

_reg_clsctx_ = comtypes.CLSCTX_INPROC_SERVER

326

327

# Supported interfaces

328

_com_interfaces_ = [IMyInterface]

329

330

def DoSomething(self, value):

331

"""Implementation of interface method."""

332

print(f"DoSomething called with value: {value}")

333

return comtypes.S_OK

334

335

# Register the class (requires admin privileges)

336

from comtypes.server.register import register_class

337

register_class(MyCoClass)

338

```

339

340

### Event Source Implementation

341

342

```python

343

import comtypes

344

from comtypes.server import COMObject

345

from comtypes.connectionpoints import IConnectionPointContainer, IConnectionPoint

346

347

# Define event interface

348

class IMyEvents(comtypes.IUnknown):

349

_iid_ = GUID("{11111111-2222-3333-4444-555555555555}")

350

_methods_ = [

351

comtypes.COMMETHOD([], comtypes.HRESULT, "OnSomethingHappened",

352

(['in'], comtypes.BSTR, "message"))

353

]

354

355

class MyEventSource(COMObject):

356

"""COM object that fires events."""

357

358

_com_interfaces_ = [IConnectionPointContainer]

359

_outgoing_interfaces_ = [IMyEvents]

360

361

def __init__(self):

362

super().__init__()

363

self._connections = {}

364

365

def fire_event(self, message):

366

"""Fire event to all connected sinks."""

367

for sink in self._connections.values():

368

try:

369

sink.OnSomethingHappened(message)

370

except Exception as e:

371

print(f"Error firing event: {e}")

372

373

# Connection point implementation would go here

374

# (simplified for example)

375

```

376

377

### In-Process Server

378

379

```python

380

# myserver.py - In-process COM server

381

import comtypes

382

from comtypes.server.inprocserver import *

383

384

class MyInProcServer(CoClass):

385

_reg_clsid_ = "{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}"

386

_reg_progid_ = "MyServer.Application.1"

387

_reg_desc_ = "My In-Process COM Server"

388

389

_com_interfaces_ = [comtypes.IUnknown]

390

391

def get_message(self):

392

return "Hello from in-process server"

393

394

# Register exported classes

395

_reg_classes_ = [MyInProcServer]

396

397

# Build as DLL and register with:

398

# regsvr32 myserver.dll

399

```

400

401

### Local Server

402

403

```python

404

# localserver.py - Local COM server

405

import comtypes

406

from comtypes.server.localserver import LocalServer

407

408

class MyLocalServer(CoClass):

409

_reg_clsid_ = "{FFFFFFFF-EEEE-DDDD-CCCC-BBBBBBBBBBBB}"

410

_reg_progid_ = "MyLocalServer.Application.1"

411

_reg_desc_ = "My Local COM Server"

412

413

_com_interfaces_ = [comtypes.IUnknown]

414

415

def get_data(self):

416

return "Data from local server"

417

418

if __name__ == "__main__":

419

# Create and run local server

420

server = LocalServer()

421

server.register_class(MyLocalServer)

422

423

print("Starting local COM server...")

424

server.run() # Blocks until shutdown

425

```

426

427

### Class Factory Implementation

428

429

```python

430

import comtypes

431

from comtypes.server import IClassFactory, COMObject

432

433

class MyClassFactory(COMObject):

434

"""Custom class factory implementation."""

435

436

_com_interfaces_ = [IClassFactory]

437

438

def __init__(self, target_class):

439

super().__init__()

440

self.target_class = target_class

441

442

def CreateInstance(self, outer, interface):

443

"""Create new instance of target class."""

444

if outer is not None:

445

raise comtypes.COMError(comtypes.hresult.CLASS_E_NOAGGREGATION)

446

447

# Create instance

448

instance = self.target_class()

449

450

# Query for requested interface

451

return instance.QueryInterface(interface)

452

453

def LockServer(self, lock):

454

"""Lock/unlock server in memory."""

455

# Implementation depends on server type

456

pass

457

```