user28918531
user28918531

Reputation: 11

Using pywin32 and flask to build a windows update scanner and i am having a problem where any function using COM objects blocks the next function

As the title states, i am trying to build a remote windows update scanner in python using pywin32 and flask. My intended functionality is for a listener to receive a post request to the /trigger endpoint and start the instruction. If i use a function that needs COM objects, in this case the Windows Update Agent API, any instruction after the function does not run.

The function in question:

def scan_for_updates():
    """
    Scans for available Windows updates using the Windows Update Agent API.
    """
    try:
        pythoncom.CoInitialize()

        # Create a session with the Windows Update Agent
        update_session = win32com.client.Dispatch("Microsoft.Update.Session")
        update_searcher = update_session.CreateUpdateSearcher()

        # Search for updates that are not installed
        search_result = update_searcher.Search("IsInstalled=0")

        if search_result.Updates.Count == 0:
            print("No updates available.")
            return []

        displayed_updates = []  # List to store non-driver updates
        print("Available Updates:\n")

        for update in search_result.Updates:
            # Skip updates in the "Drivers" category
            if any(category.Name == "Drivers" for category in update.Categories):
                continue

            # Extract update details
            title = update.Title
            description = getattr(update, "Description", "No description available")
            kb_numbers = ", ".join([f"{kb}" for kb in update.KBArticleIDs]) if update.KBArticleIDs else "N/A"
            file_size_mb = int(update.MaxDownloadSize) / (1024 * 1024) if hasattr(update, "MaxDownloadSize") else 0

            # Parse and format LastDeploymentChangeTime
            deployment_date = "N/A"
            if hasattr(update, "LastDeploymentChangeTime"):
                try:
                    deployment_date = datetime.fromisoformat(str(update.LastDeploymentChangeTime)).strftime("%d-%m-%y")
                except ValueError:
                    deployment_date = "Invalid Date"

            # Add the update details to the list
            displayed_updates.append({
                "Title": title,
                "Description": description,
                "KB Number(s)": kb_numbers,
                "File Size (MB)": file_size_mb,
                "Last Deployment Date": deployment_date
            })

            # Display the update details
            print(f"Title: {title}")
            print(f"Description: {description}")
            print(f"KB Number(s): {kb_numbers}")
            print(f"File Size: {file_size_mb:.2f} MB")
            print(f"Last Deployment Date: {deployment_date}")
            print("-" * 50)

        # Display the total number of non-driver updates
        print(f"\nTotal Updates Found (excluding Drivers): {len(displayed_updates)}")

        return displayed_updates

    except Exception as e:
        print(f"An error occurred while scanning for updates: {e}")
        return []

    finally:
        pythoncom.CoUninitialize()

This function is supposed to provide data for another function which parses this data into a CSV file. The flask app does not move on to the CSV creation function after this function.

I tried to explicitly run the function in a separate thread, that didnt yield any differences. Explicit logging did not help with showing the problem. If i combine my csv creation and update scanning into one function, i get my desired result but it still blocks any instruction happening outside the function which prevents me from sending a response to my server to move on to the next device in the scan list.

Upvotes: 1

Views: 39

Answers (0)

Related Questions