fix: fix PBI Desktop window detection and fallback chain in desktop_reload

- _find_pbi_window_pywin32: also match by PBIDesktop.exe process name so
  newer Desktop versions that title windows with just the report name are
  found correctly
- _try_pywin32: return None (not an error dict) when window is not found,
  so reload_desktop() falls through to the PowerShell fallback as intended
- bump version to 3.10.7; sync __init__.py (was stale at 3.10.5)
This commit is contained in:
MinaSaad1 2026-04-07 21:18:10 +02:00
parent 93c4275848
commit 849d309228
3 changed files with 25 additions and 11 deletions

View file

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "pbi-cli-tool"
version = "3.10.6"
version = "3.10.7"
description = "CLI for Power BI semantic models and PBIR reports - direct .NET connection for token-efficient AI agent usage"
readme = "README.pypi.md"
license = "MIT AND LicenseRef-Microsoft-AS-Client-Libraries"

View file

@ -1,3 +1,3 @@
"""pbi-cli: CLI for Power BI semantic models via direct .NET interop."""
__version__ = "3.10.5"
__version__ = "3.10.7"

View file

@ -56,11 +56,7 @@ def _try_pywin32() -> dict[str, Any] | None:
hwnd = _find_pbi_window_pywin32()
if hwnd == 0:
return {
"status": "error",
"method": "pywin32",
"message": "Power BI Desktop window not found. Is it running?",
}
return None # window not found; let fallback chain continue
try:
# Bring window to foreground
@ -93,17 +89,35 @@ def _try_pywin32() -> dict[str, Any] | None:
def _find_pbi_window_pywin32() -> int:
"""Find Power BI Desktop's main window handle via pywin32."""
import win32api
import win32con
import win32gui
import win32process
result = 0
def callback(hwnd: int, _: Any) -> bool:
nonlocal result
if win32gui.IsWindowVisible(hwnd):
title = win32gui.GetWindowText(hwnd)
if "Power BI Desktop" in title:
if not win32gui.IsWindowVisible(hwnd):
return True
title = win32gui.GetWindowText(hwnd)
if "Power BI Desktop" in title:
result = hwnd
return False
# Newer PBI Desktop versions title the window with just the report
# name (e.g. "Sales_Demo") -- fall back to matching by process name.
try:
_, pid = win32process.GetWindowThreadProcessId(hwnd)
h_proc = win32api.OpenProcess(
win32con.PROCESS_QUERY_LIMITED_INFORMATION, False, pid
)
exe_path = win32process.GetModuleFileNameEx(h_proc, 0)
win32api.CloseHandle(h_proc)
if exe_path.lower().endswith("pbidesktop.exe"):
result = hwnd
return False # Stop enumeration
return False
except Exception:
pass
return True
try: