@tanskong/office-assistant 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanskong/office-assistant",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Office Assistant - AI-powered Office automation via MCP protocol with license protection",
5
5
  "main": "bin/office-assistant.js",
6
6
  "bin": {
package/requirements.txt CHANGED
@@ -1,3 +1,4 @@
1
- fastmcp>=2.3.3
2
- pywin32>=310
3
- Pillow>=10.0.0
1
+ fastmcp>=2.3.3
2
+ pywin32>=310
3
+ Pillow>=10.0.0
4
+ psutil>=5.9.0
package/src/officer.py CHANGED
@@ -147,10 +147,35 @@ class TheOfficer:
147
147
  self.__dict__[app_name_attr] = app
148
148
  return app
149
149
  else:
150
+ # 策略1:优先尝试 GetActiveObject
150
151
  try:
151
152
  app = win32com.client.GetActiveObject(app_full_name)
152
- except pywintypes.com_error:
153
- app = win32com.client.Dispatch(app_full_name)
153
+ # 验证可用性
154
+ _ = app.Visible
155
+ self.__dict__[app_name_attr] = app
156
+ return app
157
+ except (pywintypes.com_error, Exception):
158
+ pass
159
+
160
+ # 策略2:通过进程列表查找当前用户的实例(需要 psutil)
161
+ try:
162
+ import psutil
163
+ current_user = psutil.Process().username()
164
+ for proc in psutil.process_iter(['pid', 'name', 'username']):
165
+ if proc.info['name'].lower() == app_name.lower() + '.exe' and proc.info['username'] == current_user:
166
+ pid = proc.info['pid']
167
+ # 使用动态分派绑定到指定进程
168
+ import win32com.client.dynamic
169
+ moniker = f"!{pid}"
170
+ app = win32com.client.dynamic.Dispatch(moniker)
171
+ _ = app.Visible
172
+ self.__dict__[app_name_attr] = app
173
+ return app
174
+ except Exception:
175
+ pass
176
+
177
+ # 策略3:兜底,创建新实例
178
+ app = win32com.client.Dispatch(app_full_name)
154
179
  self.__dict__[app_name_attr] = app
155
180
  return app
156
181
  except Exception as e:
package/src/server.py CHANGED
@@ -11,6 +11,7 @@ We are not responsible for data loss when operating on original file locations.
11
11
 
12
12
  import sys
13
13
  import os
14
+ from io import StringIO
14
15
 
15
16
  from license_manager import verify_license
16
17
  verify_license()
@@ -184,10 +185,17 @@ def run_python(code: str, app_name: str = "Excel") -> dict:
184
185
  doc = _get_active_doc(app, app_name)
185
186
  globals_dict = _build_globals(app, doc, app_name)
186
187
 
188
+ # Capture stdout to return print output
189
+ old_stdout = sys.stdout
190
+ sys.stdout = buffer = StringIO()
191
+
187
192
  try:
188
193
  exec(code, globals_dict)
189
- return {"success": True}
194
+ output = buffer.getvalue()
195
+ sys.stdout = old_stdout
196
+ return {"success": True, "output": output or "(无输出)"}
190
197
  except Exception as e:
198
+ sys.stdout = old_stdout
191
199
  return {"success": False, "error": str(e)}
192
200
 
193
201