diff --git a/README.md b/README.md index 6c50cae5..c1e8a203 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Examples are organized by feature category: - `working-with-exchange-webdav-client/` - 41 example(s) - `working-with-ibm-notes/` - 30 example(s) - `working-with-imap-client/` - 59 example(s) -- `working-with-microsoft-graph-client/` - 32 example(s) +- `working-with-microsoft-graph-client/` - 33 example(s) - `working-with-mime-messages/` - 121 example(s) - `working-with-outlook-storage-files/` - 61 example(s) - `working-with-pop3-client/` - 40 example(s) diff --git a/agents.md b/agents.md index 35e43ace..84ee574a 100644 --- a/agents.md +++ b/agents.md @@ -18,7 +18,7 @@ When working in this repository: - Follow the conventions and anti-patterns below exactly. ## Repository Overview -This repository currently contains **695** working code examples across **14** categories. +This repository currently contains **696** working code examples across **14** categories. ### Category Details - **convert-between-formats** — 40 examples. Guide: [agents.md](./convert-between-formats/agents.md) @@ -29,7 +29,7 @@ This repository currently contains **695** working code examples across **14** c - **working-with-exchange-webdav-client** — 41 examples. Guide: [agents.md](./working-with-exchange-webdav-client/agents.md) - **working-with-ibm-notes** — 30 examples. Guide: [agents.md](./working-with-ibm-notes/agents.md) - **working-with-imap-client** — 59 examples. Guide: [agents.md](./working-with-imap-client/agents.md) -- **working-with-microsoft-graph-client** — 32 examples. Guide: [agents.md](./working-with-microsoft-graph-client/agents.md) +- **working-with-microsoft-graph-client** — 33 examples. Guide: [agents.md](./working-with-microsoft-graph-client/agents.md) - **working-with-mime-messages** — 121 examples. Guide: [agents.md](./working-with-mime-messages/agents.md) - **working-with-outlook-storage-files** — 61 examples. Guide: [agents.md](./working-with-outlook-storage-files/agents.md) - **working-with-pop3-client** — 40 examples. Guide: [agents.md](./working-with-pop3-client/agents.md) @@ -63,5 +63,5 @@ Success = exit code 0 and no `CS####` compiler errors. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/convert-between-formats/agents.md b/convert-between-formats/agents.md index 352f9833..627b7ff8 100644 --- a/convert-between-formats/agents.md +++ b/convert-between-formats/agents.md @@ -85,5 +85,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/index.json b/index.json index 30cc7988..636c74a2 100644 --- a/index.json +++ b/index.json @@ -3,9 +3,9 @@ "platform": "net", "framework": "net8.0", "package_version": "26.1.0", - "total_examples": 695, + "total_examples": 696, "total_categories": 14, - "last_updated": "2026-04-01", + "last_updated": "2026-04-02", "categories": [ { "name": "convert-between-formats", @@ -699,16 +699,16 @@ "count": 30 }, { - "name": "System.Net", - "count": 10 + "name": "System.IO", + "count": 9 }, { - "name": "Aspose.Email.Tools.Search", - "count": 8 + "name": "System.Net", + "count": 9 }, { - "name": "System.IO", - "count": 8 + "name": "Aspose.Email.Tools.Search", + "count": 7 }, { "name": "Aspose.Email.Calendar", @@ -950,7 +950,7 @@ }, { "name": "working-with-microsoft-graph-client", - "file_count": 32, + "file_count": 33, "files": [ "authenticate-with-azure-active-directory-via-microsoft-graph-client-using-office-credentials-extracted-from-an-msg-file.cs", "copy-an-msg-format-email-message-to-a-destination-mailbox-utilizing-the-microsoft-graph-client-api.cs", @@ -973,6 +973,7 @@ "retrieve-an-msg-format-attachment-via-the-microsoft-graph-client-handling-authentication-and-response-parsing.cs", "retrieve-an-msg-formatted-email-message-using-the-microsoft-graph-client-api-and-process-its-contents.cs", "retrieve-message-rules-from-an-msg-file-by-utilizing-the-microsoft-graph-client-api.cs", + "retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs", "retrieve-the-tasks-list-embedded-within-an-msg-file-using-the-microsoft-graph-client-api.cs", "use-microsoft-graph-client-to-enumerate-steps-for-creating-an-azure-ad-admin-center-project-from-an-msg-file.cs", "utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs", @@ -988,27 +989,27 @@ "required_namespaces": [ { "name": "System", - "count": 32 + "count": 33 }, { "name": "Aspose.Email", - "count": 32 + "count": 33 }, { "name": "Aspose.Email.Clients", - "count": 32 + "count": 33 }, { "name": "Aspose.Email.Clients.Graph", - "count": 32 + "count": 33 }, { "name": "System.IO", - "count": 25 + "count": 27 }, { "name": "Aspose.Email.Mapi", - "count": 22 + "count": 26 }, { "name": "System.Collections.Generic", @@ -1170,7 +1171,7 @@ }, { "name": "Aspose.Email.Mapi", - "count": 68 + "count": 67 }, { "name": "System.Security.Cryptography.X509Certificates", @@ -1182,7 +1183,7 @@ }, { "name": "Aspose.Email.Mime", - "count": 7 + "count": 6 }, { "name": "System.Collections.Generic", @@ -1304,7 +1305,7 @@ }, { "name": "System.Collections.Generic", - "count": 9 + "count": 8 }, { "name": "Aspose.Email.Tools.Search", diff --git a/programming-email-verification/agents.md b/programming-email-verification/agents.md index 81613f57..1722c5c4 100644 --- a/programming-email-verification/agents.md +++ b/programming-email-verification/agents.md @@ -50,5 +50,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/programming-with-gmail/agents.md b/programming-with-gmail/agents.md index 5d5311ec..30a6c364 100644 --- a/programming-with-gmail/agents.md +++ b/programming-with-gmail/agents.md @@ -99,5 +99,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-amp-html-emails/agents.md b/working-with-amp-html-emails/agents.md index a3364d04..d35a0ff0 100644 --- a/working-with-amp-html-emails/agents.md +++ b/working-with-amp-html-emails/agents.md @@ -62,5 +62,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-exchange-ews-client/agents.md b/working-with-exchange-ews-client/agents.md index 445b3a1e..3194a07d 100644 --- a/working-with-exchange-ews-client/agents.md +++ b/working-with-exchange-ews-client/agents.md @@ -230,5 +230,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-exchange-webdav-client/agents.md b/working-with-exchange-webdav-client/agents.md index 03f77569..4a1e82b7 100644 --- a/working-with-exchange-webdav-client/agents.md +++ b/working-with-exchange-webdav-client/agents.md @@ -22,9 +22,9 @@ See the root [agents.md](../agents.md) for repository-wide conventions. - `using Aspose.Email;` (39 file(s)) - `using Aspose.Email.Clients.Exchange.Dav;` (32 file(s)) - `using Aspose.Email.Clients.Exchange;` (30 file(s)) -- `using System.Net;` (10 file(s)) -- `using Aspose.Email.Tools.Search;` (8 file(s)) -- `using System.IO;` (8 file(s)) +- `using System.IO;` (9 file(s)) +- `using System.Net;` (9 file(s)) +- `using Aspose.Email.Tools.Search;` (7 file(s)) - `using Aspose.Email.Calendar;` (4 file(s)) - `using Aspose.Email.Clients.Smtp;` (3 file(s)) - `using Aspose.Email.Mapi;` (3 file(s)) @@ -86,5 +86,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-exchange-webdav-client/implement-message-filtering-through-webdav-to-retrieve-only-emails-that-satisfy-defined-search-criteria-and-properties.cs b/working-with-exchange-webdav-client/implement-message-filtering-through-webdav-to-retrieve-only-emails-that-satisfy-defined-search-criteria-and-properties.cs index 48147329..9c933835 100644 --- a/working-with-exchange-webdav-client/implement-message-filtering-through-webdav-to-retrieve-only-emails-that-satisfy-defined-search-criteria-and-properties.cs +++ b/working-with-exchange-webdav-client/implement-message-filtering-through-webdav-to-retrieve-only-emails-that-satisfy-defined-search-criteria-and-properties.cs @@ -1,66 +1,77 @@ using Aspose.Email.Clients.Exchange; using System; -using System.Net; +using System.IO; using Aspose.Email; using Aspose.Email.Clients.Exchange.Dav; -using Aspose.Email.Tools.Search; -namespace AsposeEmailWebDavFilterExample +class Program { - class Program + static void Main() { - static void Main() + try { - try - { - // Placeholder connection settings – replace with real values. - string serverUri = "https://exchange.example.com/EWS/Exchange.asmx"; - string username = "username"; - string password = "password"; + // Placeholder connection settings + string mailboxUri = "https://exchange.example.com/ews/Exchange.asmx"; + string username = "username"; + string password = "password"; - // Guard against executing with placeholder credentials. - if (serverUri.Contains("example.com") || username == "username" || password == "password") - { - Console.Error.WriteLine("Placeholder credentials detected. Skipping execution."); - return; - } + // Skip execution if placeholder credentials are detected + if (mailboxUri.Contains("example.com") || username == "username") + { + Console.Error.WriteLine("Placeholder credentials detected. Skipping execution."); + return; + } - // Create and connect the Exchange WebDAV client. + // Create and use the Exchange client + using (ExchangeClient client = new ExchangeClient(mailboxUri, username, password)) + { try { - using (ExchangeClient client = new ExchangeClient(serverUri, username, password)) + // Retrieve messages from the Inbox folder that match the query. + string query = "HasAttachment = True AND IsRead = False"; + ExchangeMessageInfoCollection messages = client.ListMessages(client.MailboxInfo.InboxUri, query); + foreach (var msgInfo in messages) { - // Build a query to retrieve only unread messages that have attachments. - // The query language follows the Exchange MailQuery syntax. - MailQuery query = new MailQuery("HasAttachment = True AND IsRead = False"); + // Fetch the full message + using (MailMessage message = client.FetchMessage(msgInfo.UniqueUri)) + { + Console.WriteLine($"Subject: {message.Subject}"); - // List messages from the Inbox that match the query (recursive = false). - ExchangeMessageInfoCollection messages = client.ListMessages( - client.MailboxInfo.InboxUri, - query, - false); + // Prepare output directory and file path + string outputDir = "Output"; + string outputPath = Path.Combine(outputDir, "FirstMessage.eml"); - // Process the filtered messages. - foreach (ExchangeMessageInfo info in messages) - { - Console.WriteLine("Subject: " + info.Subject); - Console.WriteLine("Has Attachments: " + info.HasAttachments); - Console.WriteLine("Received: " + info.InternalDate); - Console.WriteLine(new string('-', 40)); + // Ensure the output directory exists + if (!Directory.Exists(outputDir)) + { + Directory.CreateDirectory(outputDir); + } + + // Save the message to a file with error handling + try + { + message.Save(outputPath); + Console.WriteLine($"Message saved to {outputPath}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to save message: {ex.Message}"); + } } + + // Process only the first message + break; } } catch (Exception ex) { - Console.Error.WriteLine("Error during client operation: " + ex.Message); - return; + Console.Error.WriteLine($"Error during Exchange operations: {ex.Message}"); } } - catch (Exception ex) - { - Console.Error.WriteLine("Unhandled exception: " + ex.Message); - return; - } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Unhandled exception: {ex.Message}"); } } } diff --git a/working-with-ibm-notes/agents.md b/working-with-ibm-notes/agents.md index ed791061..bb3cf9c9 100644 --- a/working-with-ibm-notes/agents.md +++ b/working-with-ibm-notes/agents.md @@ -73,5 +73,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-imap-client/agents.md b/working-with-imap-client/agents.md index a9d9d9a9..9361482d 100644 --- a/working-with-imap-client/agents.md +++ b/working-with-imap-client/agents.md @@ -109,5 +109,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-microsoft-graph-client/agents.md b/working-with-microsoft-graph-client/agents.md index 745b8430..7dd1ce38 100644 --- a/working-with-microsoft-graph-client/agents.md +++ b/working-with-microsoft-graph-client/agents.md @@ -18,12 +18,12 @@ See the root [agents.md](../agents.md) for repository-wide conventions. - Files are standalone `.cs` examples stored directly in this folder. ## Required Namespaces -- `using System;` (32 file(s)) -- `using Aspose.Email;` (32 file(s)) -- `using Aspose.Email.Clients;` (32 file(s)) -- `using Aspose.Email.Clients.Graph;` (32 file(s)) -- `using System.IO;` (25 file(s)) -- `using Aspose.Email.Mapi;` (22 file(s)) +- `using System;` (33 file(s)) +- `using Aspose.Email;` (33 file(s)) +- `using Aspose.Email.Clients;` (33 file(s)) +- `using Aspose.Email.Clients.Graph;` (33 file(s)) +- `using System.IO;` (27 file(s)) +- `using Aspose.Email.Mapi;` (26 file(s)) - `using System.Collections.Generic;` (3 file(s)) - `using Aspose.Email.Clients.Exchange;` (2 file(s)) - `using Aspose.Email.Calendar;` (1 file(s)) @@ -53,6 +53,7 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | [retrieve-an-msg-format-attachment-via-the-microsoft-graph-client-handling-authentication-and-response-parsing.cs](./retrieve-an-msg-format-attachment-via-the-microsoft-graph-client-handling-authentication-and-response-parsing.cs) | retrieve an msg format attachment via the microsoft graph client handling authentication and response parsing | | [retrieve-an-msg-formatted-email-message-using-the-microsoft-graph-client-api-and-process-its-contents.cs](./retrieve-an-msg-formatted-email-message-using-the-microsoft-graph-client-api-and-process-its-contents.cs) | retrieve an msg formatted email message using the microsoft graph client api and process its contents | | [retrieve-message-rules-from-an-msg-file-by-utilizing-the-microsoft-graph-client-api.cs](./retrieve-message-rules-from-an-msg-file-by-utilizing-the-microsoft-graph-client-api.cs) | retrieve message rules from an msg file by utilizing the microsoft graph client api | +| [retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs](./retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs) | retrieve the message category from an msg file using the microsoft graph client library | | [retrieve-the-tasks-list-embedded-within-an-msg-file-using-the-microsoft-graph-client-api.cs](./retrieve-the-tasks-list-embedded-within-an-msg-file-using-the-microsoft-graph-client-api.cs) | retrieve the tasks list embedded within an msg file using the microsoft graph client api | | [use-microsoft-graph-client-to-enumerate-steps-for-creating-an-azure-ad-admin-center-project-from-an-msg-file.cs](./use-microsoft-graph-client-to-enumerate-steps-for-creating-an-azure-ad-admin-center-project-from-an-msg-file.cs) | use microsoft graph client to enumerate steps for creating an azure ad admin center project from an msg file | | [utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs](./utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs) | utilize microsoft graph client to add the msal net package and install the microsoft identity client nuget containing | @@ -66,7 +67,7 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | [utilize-the-microsoft-graph-client-to-retrieve-and-display-the-newly-registered-applications-blade-from-msg-format.cs](./utilize-the-microsoft-graph-client-to-retrieve-and-display-the-newly-registered-applications-blade-from-msg-format.cs) | utilize the microsoft graph client to retrieve and display the newly registered applications blade from msg format | ## Category Statistics -- Total examples: 32 +- Total examples: 33 ## General Tips - Follow root boundaries and testing guide. @@ -75,5 +76,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-microsoft-graph-client/create-a-notebook-from-an-msg-file-programmatically-using-the-microsoft-graph-client-api.cs b/working-with-microsoft-graph-client/create-a-notebook-from-an-msg-file-programmatically-using-the-microsoft-graph-client-api.cs index 60a733d7..9c2487cb 100644 --- a/working-with-microsoft-graph-client/create-a-notebook-from-an-msg-file-programmatically-using-the-microsoft-graph-client-api.cs +++ b/working-with-microsoft-graph-client/create-a-notebook-from-an-msg-file-programmatically-using-the-microsoft-graph-client-api.cs @@ -1,60 +1,121 @@ using System; using System.IO; using Aspose.Email; +using Aspose.Email.Mapi; using Aspose.Email.Clients; using Aspose.Email.Clients.Graph; - class Program { - static void Main() + static void Main(string[] args) { try { - // Path to the MSG file - string msgPath = "sample.msg"; + // Placeholder credentials – replace with real values. + string clientId = "your-client-id"; + string clientSecret = "your-client-secret"; + string refreshToken = "your-refresh-token"; + string tenantId = "your-tenant-id"; - // Verify the input file exists - if (!File.Exists(msgPath)) + // Guard against placeholder credentials to avoid live calls in CI. + if (clientId.StartsWith("your-") || clientSecret.StartsWith("your-") || refreshToken.StartsWith("your-") || tenantId.StartsWith("your-")) { - Console.Error.WriteLine($"Input file not found: {msgPath}"); + Console.Error.WriteLine("Placeholder credentials detected. Skipping Graph operations."); return; } - // Load the MSG file into a MailMessage (disposed after use) - using (FileStream msgStream = File.OpenRead(msgPath)) + // Initialize token provider. + Aspose.Email.Clients.ITokenProvider tokenProvider; + try { - using (MailMessage message = MailMessage.Load(msgStream)) - { - // Message loaded – you can access its properties if needed - // For this example we only need to ensure the file is read successfully - } + tokenProvider = TokenProvider.Outlook.GetInstance(clientId, clientSecret, refreshToken); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create token provider: {ex.Message}"); + return; } - // Create a token provider for Outlook (3‑argument overload) - Aspose.Email.Clients.ITokenProvider tokenProvider = TokenProvider.Outlook.GetInstance( - "clientId", - "clientSecret", - "refreshToken"); + // Create Graph client. + IGraphClient client; + try + { + client = GraphClient.GetClient(tokenProvider, tenantId); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create Graph client: {ex.Message}"); + return; + } - // Initialize the Graph client (disposable) - using (IGraphClient client = GraphClient.GetClient(tokenProvider, "")) + using (client) { - // Define a new OneNote notebook - Notebook notebook = new Notebook + // Path to the MSG file. + string msgPath = "sample.msg"; + + // Verify the MSG file exists. + if (!File.Exists(msgPath)) + { + try { - DisplayName = "ImportedNotebook" - }; + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } - // Create the notebook in the user's OneNote library - Notebook createdNotebook = client.CreateNotebook(notebook); + Console.Error.WriteLine($"Input file not found: {msgPath}"); + return; + } - // Output the identifier of the created notebook - Console.WriteLine($"Notebook created with ID: {createdNotebook.Id}"); + // Load the MSG file into a MapiMessage. + MapiMessage mapMessage; + try + { + mapMessage = MapiMessage.Load(msgPath); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to load MSG file: {ex.Message}"); + return; + } + + using (mapMessage) + { + // Create a Notebook object using the message subject as the notebook name. + Notebook newNotebook = new Notebook + { + DisplayName = mapMessage.Subject ?? "Untitled Notebook" + }; + + // Create the notebook via Graph client. + Notebook createdNotebook; + try + { + createdNotebook = client.CreateNotebook(newNotebook); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create notebook: {ex.Message}"); + return; + } + + // Output the created notebook details. + Console.WriteLine($"Notebook created successfully. ID: {createdNotebook.Id}, Name: {createdNotebook.DisplayName}"); + } } } catch (Exception ex) { - Console.Error.WriteLine(ex.Message); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); } } } diff --git a/working-with-microsoft-graph-client/retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs b/working-with-microsoft-graph-client/retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs new file mode 100644 index 00000000..0bd616ee --- /dev/null +++ b/working-with-microsoft-graph-client/retrieve-the-message-category-from-an-msg-file-using-the-microsoft-graph-client-library.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; +using Aspose.Email; +using Aspose.Email.Mapi; +using Aspose.Email.Clients; +using Aspose.Email.Clients.Graph; + +class Program +{ + static void Main() + { + try + { + // Placeholder credentials – skip actual network call if not replaced + string clientId = "your-client-id"; + string clientSecret = "your-client-secret"; + string refreshToken = "your-refresh-token"; + + if (clientId == "your-client-id" || + clientSecret == "your-client-secret" || + refreshToken == "your-refresh-token") + { + Console.Error.WriteLine("Placeholder Graph credentials detected. Skipping Graph operations."); + return; + } + + // Path to the MSG file + string msgPath = "message.msg"; + + if (!File.Exists(msgPath)) + { + try + { + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } + + Console.Error.WriteLine($"MSG file not found at path: {msgPath}"); + return; + } + + // Load the MSG file + MapiMessage msg; + try + { + msg = MapiMessage.Load(msgPath); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to load MSG file: {ex.Message}"); + return; + } + + // Retrieve the first category name from the message (if any) + string[] categories = msg.Categories; + if (categories == null || categories.Length == 0) + { + Console.WriteLine("No categories assigned to the message."); + return; + } + + string categoryName = categories[0]; + Console.WriteLine($"Category name from MSG: {categoryName}"); + + // Create token provider and Graph client + Aspose.Email.Clients.ITokenProvider tokenProvider = Aspose.Email.Clients.TokenProvider.Outlook.GetInstance(clientId, clientSecret, refreshToken); + using (IGraphClient client = GraphClient.GetClient(tokenProvider, "https://graph.microsoft.com")) + { + try + { + // Fetch the category details from Graph using the category name as ID placeholder + // In a real scenario, replace 'categoryId' with the actual OutlookCategory ID. + string categoryId = categoryName; // placeholder mapping + OutlookCategory fetchedCategory = client.FetchCategory(categoryId); + Console.WriteLine($"Fetched Category Display Name: {fetchedCategory.DisplayName}"); + Console.WriteLine($"Fetched Category Color: {fetchedCategory.Color}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Graph operation failed: {ex.Message}"); + } + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); + } + } +} diff --git a/working-with-microsoft-graph-client/utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs b/working-with-microsoft-graph-client/utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs index eb4ea3a1..be8a97b5 100644 --- a/working-with-microsoft-graph-client/utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs +++ b/working-with-microsoft-graph-client/utilize-microsoft-graph-client-to-add-the-msal-net-package-and-install-the-microsoft-identity-client-nuget-containing.cs @@ -1,7 +1,9 @@ +using Aspose.Email.Clients; using System; +using System.IO; using Aspose.Email; -using Aspose.Email.Clients; using Aspose.Email.Clients.Graph; +using Aspose.Email.Mapi; class Program { @@ -9,28 +11,101 @@ static void Main() { try { - // Create Outlook token provider (3‑argument overload) - TokenProvider tokenProvider = TokenProvider.Outlook.GetInstance( - "clientId", - "clientSecret", - "refreshToken"); - - // Initialize Graph client for a specific tenant - using (IGraphClient client = GraphClient.GetClient(tokenProvider, "tenantId")) + // Placeholder authentication parameters + string clientId = "your-client-id"; + string clientSecret = "your-client-secret"; + string refreshToken = "your-refresh-token"; + string tenantId = "your-tenant-id"; + string userEmail = "user@example.com"; + + // Skip execution if placeholders are not replaced + if (clientId.StartsWith("your-") || clientSecret.StartsWith("your-") || + refreshToken.StartsWith("your-") || tenantId.StartsWith("your-")) + { + Console.Error.WriteLine("Authentication parameters are placeholders. Skipping Graph operations."); + return; + } + + // Path to the MSG file to be uploaded + string msgPath = "SampleMessage.msg"; + + // Ensure the MSG file exists; create a minimal placeholder if missing + if (!File.Exists(msgPath)) + { + try + { + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } + + try + { + using (MapiMessage placeholder = new MapiMessage()) + { + placeholder.Subject = "Placeholder Subject"; + placeholder.Body = "Placeholder body."; + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create placeholder MSG file: {ex.Message}"); + return; + } + } + + // Load the MSG file into a MailMessage instance + MailMessage mailMessage; + try + { + MapiMessage mapiMsg = MapiMessage.Load(msgPath); + mailMessage = mapiMsg.ToMailMessage(new MailConversionOptions()); + } + catch (Exception ex) { - // List messages from the Inbox folder (folder identifier is the well‑known name) - MessageInfoCollection messages = client.ListMessages("Inbox"); + Console.Error.WriteLine($"Failed to load MSG file: {ex.Message}"); + return; + } + + // Create token provider for Outlook (MSAL) + Aspose.Email.Clients.TokenProvider tokenProvider = Aspose.Email.Clients.TokenProvider.Outlook.GetInstance( + clientId, clientSecret, refreshToken); + + // Initialize Graph client + using (IGraphClient client = GraphClient.GetClient(tokenProvider, tenantId)) + { + // Set the user (resource) for which the operations will be performed + client.ResourceId = userEmail; - foreach (MessageInfo message in messages) + // Target folder ID (e.g., Inbox). In a real scenario, retrieve the actual folder ID. + string folderId = "Inbox"; + + try + { + // Create the message in the specified folder + client.CreateMessage(folderId, mailMessage); + Console.WriteLine("Message created successfully in folder: " + folderId); + } + catch (Exception ex) { - // Output basic information; avoid using non‑existent Id property - Console.WriteLine($"Subject: {message.Subject}"); + Console.Error.WriteLine($"Failed to create message via Graph: {ex.Message}"); } } } catch (Exception ex) { - Console.Error.WriteLine($"Error: {ex.Message}"); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); } } } diff --git a/working-with-microsoft-graph-client/utilize-the-microsoft-graph-client-to-configure-graph-api-permissions-extracted-from-an-msg-file.cs b/working-with-microsoft-graph-client/utilize-the-microsoft-graph-client-to-configure-graph-api-permissions-extracted-from-an-msg-file.cs index d288b104..8049ccc8 100644 --- a/working-with-microsoft-graph-client/utilize-the-microsoft-graph-client-to-configure-graph-api-permissions-extracted-from-an-msg-file.cs +++ b/working-with-microsoft-graph-client/utilize-the-microsoft-graph-client-to-configure-graph-api-permissions-extracted-from-an-msg-file.cs @@ -1,6 +1,7 @@ using System; using System.IO; using Aspose.Email; +using Aspose.Email.Mapi; using Aspose.Email.Clients; using Aspose.Email.Clients.Graph; @@ -10,24 +11,50 @@ static void Main() { try { - string msgPath = "sample.msg"; + // Paths for the MSG file + const string msgPath = "sample.msg"; - // Ensure the input MSG file exists; create a minimal placeholder if missing. + // Ensure the MSG file exists; create a minimal placeholder if missing if (!File.Exists(msgPath)) { - using (MailMessage placeholder = new MailMessage("sender@example.com", "receiver@example.com", "Subject", "Body")) + try { - placeholder.Save(msgPath); + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } + + try + { + using (var placeholder = new MapiMessage()) + { + placeholder.Subject = "Placeholder"; + placeholder.Body = "This is a placeholder MSG file."; + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create placeholder MSG file: {ex.Message}"); + return; } - Console.Error.WriteLine($"Input file not found. Created placeholder at {msgPath}."); - return; } - // Load the MSG file. - MailMessage message; + // Load the MSG file + MapiMessage msg; try { - message = MailMessage.Load(msgPath); + msg = MapiMessage.Load(msgPath); } catch (Exception ex) { @@ -35,19 +62,49 @@ static void Main() return; } - using (message) + using (msg) { - string senderEmail = message.From?.Address ?? "unknown@example.com"; + // Extract categories from the message + string[] categories = msg.Categories ?? Array.Empty(); + if (categories.Length == 0) + { + Console.WriteLine("No categories found in the MSG file."); + return; + } - // Initialize token provider for Outlook (dummy credentials). - Aspose.Email.Clients.TokenProvider tokenProvider = Aspose.Email.Clients.TokenProvider.Outlook.GetInstance( - "clientId", "clientSecret", "refreshToken"); + // Placeholder token provider credentials + const string clientId = "your-client-id"; + const string clientSecret = "your-client-secret"; + const string refreshToken = "your-refresh-token"; + const string tenantId = "your-tenant-id"; - // Create Graph client. + // Guard against placeholder credentials + if (clientId.StartsWith("your-") || + clientSecret.StartsWith("your-") || + refreshToken.StartsWith("your-") || + tenantId.StartsWith("your-")) + { + Console.WriteLine("Placeholder credentials detected. Skipping Graph API calls."); + return; + } + + // Create token provider + Aspose.Email.Clients.ITokenProvider tokenProvider; + try + { + tokenProvider = Aspose.Email.Clients.TokenProvider.Outlook.GetInstance(clientId, clientSecret, refreshToken); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create token provider: {ex.Message}"); + return; + } + + // Initialize Graph client IGraphClient client; try { - client = GraphClient.GetClient(tokenProvider, "tenantId"); + client = GraphClient.GetClient(tokenProvider, tenantId); } catch (Exception ex) { @@ -57,15 +114,18 @@ static void Main() using (client) { - // Create or update a classification override for the sender. - try - { - client.CreateOrUpdateOverride(new MailAddress(senderEmail), ClassificationType.Focused); - Console.WriteLine("Override created/updated successfully."); - } - catch (Exception ex) + // Create each category in the user's master list + foreach (string category in categories) { - Console.Error.WriteLine($"Failed to create/update override: {ex.Message}"); + try + { + client.CreateCategory(category, CategoryPreset.None); + Console.WriteLine($"Created category: {category}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create category '{category}': {ex.Message}"); + } } } } diff --git a/working-with-mime-messages/agents.md b/working-with-mime-messages/agents.md index 50ac5448..ecfd2cb1 100644 --- a/working-with-mime-messages/agents.md +++ b/working-with-mime-messages/agents.md @@ -21,10 +21,10 @@ See the root [agents.md](../agents.md) for repository-wide conventions. - `using System;` (121 file(s)) - `using Aspose.Email;` (121 file(s)) - `using System.IO;` (118 file(s)) -- `using Aspose.Email.Mapi;` (68 file(s)) +- `using Aspose.Email.Mapi;` (67 file(s)) - `using System.Security.Cryptography.X509Certificates;` (14 file(s)) - `using Aspose.Email.Calendar;` (12 file(s)) -- `using Aspose.Email.Mime;` (7 file(s)) +- `using Aspose.Email.Mime;` (6 file(s)) - `using System.Collections.Generic;` (2 file(s)) - `using System.Net.Mime;` (2 file(s)) - `using Aspose.Email.Storage.Pst;` (1 file(s)) @@ -168,5 +168,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-mime-messages/insert-a-custom-header-named-x-my-property-with-value-12345-into-an-msg-email-via-customheaders-add.cs b/working-with-mime-messages/insert-a-custom-header-named-x-my-property-with-value-12345-into-an-msg-email-via-customheaders-add.cs index f245f780..d4d2b25e 100644 --- a/working-with-mime-messages/insert-a-custom-header-named-x-my-property-with-value-12345-into-an-msg-email-via-customheaders-add.cs +++ b/working-with-mime-messages/insert-a-custom-header-named-x-my-property-with-value-12345-into-an-msg-email-via-customheaders-add.cs @@ -1,8 +1,6 @@ using System; using System.IO; using Aspose.Email; -using Aspose.Email.Mapi; -using Aspose.Email.Mime; class Program { @@ -10,48 +8,51 @@ static void Main() { try { - string inputPath = "input.msg"; - string outputPath = "output.msg"; + string msgPath = "sample.msg"; - // Ensure the input file exists; create a minimal placeholder if missing - if (!File.Exists(inputPath)) + // Ensure the MSG file exists; create a minimal placeholder if it does not. + if (!File.Exists(msgPath)) { try { - using (MapiMessage placeholder = new MapiMessage()) + using (MailMessage placeholder = new MailMessage( + "sender@example.com", + "recipient@example.com", + "Placeholder Subject", + "Placeholder body.")) { - placeholder.Subject = "Placeholder"; - placeholder.Save(inputPath); + placeholder.Save(msgPath, new MsgSaveOptions(MailMessageSaveType.OutlookMessageFormat)); } } catch (Exception ex) { - Console.Error.WriteLine($"Failed to create placeholder MSG file: {ex.Message}"); + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); return; } - } - // Load the MSG file, add a custom header, and save the result - try - { - using (MapiMessage message = MapiMessage.Load(inputPath)) + using (MailMessage placeholder = new MailMessage("from@example.com", "to@example.com", "Placeholder", "Body")) { - // Add custom header X-My-Property with value 12345 - message.Headers.Add("X-My-Property", "12345"); - - // Save the modified message - message.Save(outputPath); + placeholder.Save(msgPath, new MsgSaveOptions(MailMessageSaveType.OutlookMessageFormat)); } } - catch (Exception ex) + + // Load the MSG, add a custom header, display all headers, and save back. + using (MailMessage mail = MailMessage.Load(msgPath)) { - Console.Error.WriteLine($"Error processing MSG file: {ex.Message}"); - return; + mail.Headers.Add("X-My-Property", "12345"); + + // Iterate headers using Keys as required. + foreach (string key in mail.Headers.Keys) + { + Console.WriteLine($"{key}: {mail.Headers[key]}"); + } + + mail.Save(msgPath, new MsgSaveOptions(MailMessageSaveType.OutlookMessageFormat)); } } catch (Exception ex) { - Console.Error.WriteLine($"Unexpected error: {ex.Message}"); + Console.Error.WriteLine(ex.Message); } } } diff --git a/working-with-mime-messages/iterate-the-tnefreader-over-an-msg-message-retrieving-each-attachment-in-a-loop-via-while-reader-readnextattachment.cs b/working-with-mime-messages/iterate-the-tnefreader-over-an-msg-message-retrieving-each-attachment-in-a-loop-via-while-reader-readnextattachment.cs index 71840b44..7ea5d365 100644 --- a/working-with-mime-messages/iterate-the-tnefreader-over-an-msg-message-retrieving-each-attachment-in-a-loop-via-while-reader-readnextattachment.cs +++ b/working-with-mime-messages/iterate-the-tnefreader-over-an-msg-message-retrieving-each-attachment-in-a-loop-via-while-reader-readnextattachment.cs @@ -9,33 +9,98 @@ static void Main() { try { - string msgPath = "sample.msg"; + // Input MSG file path + string msgPath = @"C:\Temp\sample.msg"; + // Output directory for extracted attachments + string outputDir = @"C:\Temp\Attachments"; - // Ensure the MSG file exists before attempting to read it + // Verify input file exists if (!File.Exists(msgPath)) { + try + { + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } + Console.Error.WriteLine($"Input file not found: {msgPath}"); + // Optionally create a minimal placeholder MSG to continue + try + { + MapiMessage placeholder = new MapiMessage("Placeholder Subject", "Placeholder Body", "sender@example.com", "recipient@example.com"); + placeholder.Save(msgPath); + Console.WriteLine($"Created placeholder MSG at {msgPath}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create placeholder MSG: {ex.Message}"); + return; + } + } + + // Ensure output directory exists + try + { + Directory.CreateDirectory(outputDir); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Failed to create output directory: {ex.Message}"); return; } - // Read the MSG file using MapiMessageReader - using (MapiMessageReader reader = new MapiMessageReader(msgPath)) + // Load the MSG file + using (MapiMessage msg = MapiMessage.Load(msgPath)) { - using (MapiMessage message = reader.ReadMessage()) + // Iterate over attachments + foreach (MapiAttachment attachment in msg.Attachments) { - // Iterate over each attachment in the message - foreach (MapiAttachment attachment in message.Attachments) + // Determine a safe file name + string fileName = !string.IsNullOrEmpty(attachment.FileName) + ? attachment.FileName + : (!string.IsNullOrEmpty(attachment.LongFileName) ? attachment.LongFileName : "attachment.bin"); + + // Combine with output directory + string outputPath = Path.Combine(outputDir, fileName); + + // Write attachment bytes to file + try + { + using (FileStream fileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write)) + { + byte[] data = attachment.BinaryData; + if (data != null && data.Length > 0) + { + fileStream.Write(data, 0, data.Length); + Console.WriteLine($"Saved attachment: {outputPath}"); + } + else + { + Console.WriteLine($"Attachment {fileName} has no data."); + } + } + } + catch (Exception ex) { - Console.WriteLine($"Attachment: {attachment.FileName}"); - // Save the attachment to the current directory - attachment.Save(attachment.FileName); + Console.Error.WriteLine($"Failed to save attachment {fileName}: {ex.Message}"); } } } } catch (Exception ex) { - Console.Error.WriteLine($"Error: {ex.Message}"); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); } } } diff --git a/working-with-mime-messages/transform-tnef-email-attachments-into-standard-compatible-formats-by-exporting-them-as-msg-files.cs b/working-with-mime-messages/transform-tnef-email-attachments-into-standard-compatible-formats-by-exporting-them-as-msg-files.cs index 8b91fecb..9cca3629 100644 --- a/working-with-mime-messages/transform-tnef-email-attachments-into-standard-compatible-formats-by-exporting-them-as-msg-files.cs +++ b/working-with-mime-messages/transform-tnef-email-attachments-into-standard-compatible-formats-by-exporting-them-as-msg-files.cs @@ -9,24 +9,100 @@ static void Main() { try { - string tnefFilePath = "winmail.dat"; - string msgOutputPath = "output.msg"; + // Define input and output locations + string inputFilePath = "input.eml"; + string outputDirectory = "output"; - if (!File.Exists(tnefFilePath)) + // Ensure input file exists; create a minimal placeholder if missing + if (!File.Exists(inputFilePath)) { - Console.Error.WriteLine($"Error: File not found – {tnefFilePath}"); + try + { + string placeholderContent = "From: sender@example.com\r\nTo: recipient@example.com\r\nSubject: Placeholder\r\n\r\nThis is a placeholder email."; + File.WriteAllText(inputFilePath, placeholderContent); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder input file: {ex.Message}"); + return; + } + } + + // Ensure output directory exists + if (!Directory.Exists(outputDirectory)) + { + try + { + Directory.CreateDirectory(outputDirectory); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating output directory: {ex.Message}"); + return; + } + } + + // Load the email with TNEF attachment preservation + EmlLoadOptions loadOptions = new EmlLoadOptions + { + PreserveTnefAttachments = true, + PreserveEmbeddedMessageFormat = true + }; + + MailMessage mailMessage; + try + { + mailMessage = MailMessage.Load(inputFilePath, loadOptions); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error loading email file: {ex.Message}"); return; } - using (MapiMessage tnefMessage = MapiMessage.LoadFromTnef(tnefFilePath)) + // Process each attachment + foreach (Attachment attachment in mailMessage.Attachments) { - tnefMessage.Save(msgOutputPath); - Console.WriteLine($"TNEF attachment exported to MSG: {msgOutputPath}"); + if (attachment.IsTnef) + { + // Load the TNEF attachment as a MapiMessage + MapiMessage tnefMessage; + try + { + using (Stream tnefStream = attachment.ContentStream) + { + tnefMessage = MapiMessage.LoadFromTnef(tnefStream); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error loading TNEF attachment '{attachment.Name}': {ex.Message}"); + continue; + } + + // Determine output MSG file path + string safeName = string.IsNullOrEmpty(attachment.Name) ? "attachment" : Path.GetFileNameWithoutExtension(attachment.Name); + string outputMsgPath = Path.Combine(outputDirectory, safeName + ".msg"); + + // Save the MapiMessage as MSG + try + { + tnefMessage.Save(outputMsgPath); + Console.WriteLine($"Saved MSG file: {outputMsgPath}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error saving MSG file '{outputMsgPath}': {ex.Message}"); + } + } } + + // Dispose the loaded MailMessage + mailMessage.Dispose(); } catch (Exception ex) { - Console.Error.WriteLine($"Error: {ex.Message}"); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); } } } diff --git a/working-with-mime-messages/validate-the-digital-signature-of-an-msg-email-message-to-ensure-its-authenticity-and-integrity.cs b/working-with-mime-messages/validate-the-digital-signature-of-an-msg-email-message-to-ensure-its-authenticity-and-integrity.cs index 285c0f8e..5702838d 100644 --- a/working-with-mime-messages/validate-the-digital-signature-of-an-msg-email-message-to-ensure-its-authenticity-and-integrity.cs +++ b/working-with-mime-messages/validate-the-digital-signature-of-an-msg-email-message-to-ensure-its-authenticity-and-integrity.cs @@ -12,45 +12,56 @@ static void Main() { string msgPath = "sample.msg"; - // Verify that the MSG file exists before attempting to load it. + // Guard file existence if (!File.Exists(msgPath)) { + try + { + using (MapiMessage placeholder = new MapiMessage( + "from@example.com", + "to@example.com", + "Placeholder Subject", + "Placeholder body.")) + { + placeholder.Save(msgPath); + } + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error creating placeholder MSG: {ex.Message}"); + return; + } + Console.Error.WriteLine($"File not found: {msgPath}"); return; } - // Load the MSG file into a MapiMessage instance. - using (MapiMessage msg = MapiMessage.Load(msgPath)) + // Load MSG file + using (MapiMessage mapimsg = MapiMessage.Load(msgPath)) { - // Check whether the message is signed. - if (!msg.IsSigned) + // Convert to MailMessage with required options + using (MailMessage mail = mapimsg.ToMailMessage(new MailConversionOptions())) { - Console.WriteLine("The message is not signed."); - return; - } - - try - { - // Validate the digital signature and retrieve signer certificates. - X509Certificate2[] signerCertificates = msg.CheckSignature(); - - Console.WriteLine($"Signature is valid. Number of signers: {signerCertificates.Length}"); - foreach (X509Certificate2 cert in signerCertificates) + if (mail.IsSigned) { - Console.WriteLine($"Signer Subject: {cert.Subject}"); + // Verify signature and retrieve signer certificates + X509Certificate2[] signers = mail.CheckSignature(); + Console.WriteLine($"Signature is valid. Number of signers: {signers.Length}"); + foreach (var cert in signers) + { + Console.WriteLine($"Signer: {cert.Subject}"); + } + } + else + { + Console.WriteLine("The message is not signed."); } - } - catch (Exception ex) - { - // Handle signature validation errors (e.g., invalid signature, unsupported type). - Console.Error.WriteLine($"Signature validation failed: {ex.Message}"); } } } catch (Exception ex) { - // Catch any unexpected errors. - Console.Error.WriteLine($"Unexpected error: {ex.Message}"); + Console.Error.WriteLine($"Error: {ex.Message}"); } } } diff --git a/working-with-outlook-storage-files/agents.md b/working-with-outlook-storage-files/agents.md index 0e2fcb36..329c3d83 100644 --- a/working-with-outlook-storage-files/agents.md +++ b/working-with-outlook-storage-files/agents.md @@ -23,7 +23,7 @@ See the root [agents.md](../agents.md) for repository-wide conventions. - `using Aspose.Email.Storage.Pst;` (61 file(s)) - `using Aspose.Email;` (53 file(s)) - `using Aspose.Email.Mapi;` (37 file(s)) -- `using System.Collections.Generic;` (9 file(s)) +- `using System.Collections.Generic;` (8 file(s)) - `using Aspose.Email.Tools.Search;` (3 file(s)) - `using System.Collections;` (1 file(s)) - `using System.Linq;` (1 file(s)) @@ -105,5 +105,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-outlook-storage-files/execute-bulk-removal-of-items-within-outlook-pst-storage-files-utilizing-the-pst-format-s-capabilities.cs b/working-with-outlook-storage-files/execute-bulk-removal-of-items-within-outlook-pst-storage-files-utilizing-the-pst-format-s-capabilities.cs index 3b447190..cdeb158c 100644 --- a/working-with-outlook-storage-files/execute-bulk-removal-of-items-within-outlook-pst-storage-files-utilizing-the-pst-format-s-capabilities.cs +++ b/working-with-outlook-storage-files/execute-bulk-removal-of-items-within-outlook-pst-storage-files-utilizing-the-pst-format-s-capabilities.cs @@ -1,7 +1,7 @@ +using Aspose.Email; using System; -using System.IO; using System.Collections.Generic; -using Aspose.Email; +using System.IO; using Aspose.Email.Storage.Pst; class Program @@ -10,50 +10,113 @@ static void Main() { try { - string pstPath = "sample.pst"; - - // Verify that the PST file exists before attempting to open it. - if (!File.Exists(pstPath)) - { - Console.Error.WriteLine($"Error: File not found – {pstPath}"); - return; - } + // Paths for the source PST and the resulting PST after deletions + string sourcePstPath = "sample.pst"; + string resultPstPath = "sample_modified.pst"; - // Open the PST file with write access. - using (PersonalStorage pst = PersonalStorage.FromFile(pstPath, true)) + // Ensure the source PST exists; if not, create an empty placeholder PST + if (!File.Exists(sourcePstPath)) { - // Retrieve the Inbox folder (standard IPM folder). - FolderInfo inbox = pst.GetPredefinedFolder(StandardIpmFolder.Inbox); - if (inbox == null) + try { - Console.Error.WriteLine("Error: Inbox folder not found in the PST."); - return; + // Create an empty Unicode PST file + using (PersonalStorage placeholder = PersonalStorage.Create(sourcePstPath, FileFormatVersion.Unicode)) + { + // Optionally, create a default Inbox folder + placeholder.CreatePredefinedFolder("Inbox", StandardIpmFolder.Inbox); + } } - - // Collect entry IDs of all messages in the folder. - List entryIds = new List(); - foreach (MessageInfo msgInfo in inbox.EnumerateMessages()) + catch (Exception ex) { - // EntryIdString provides the string representation of the entry ID. - entryIds.Add(msgInfo.EntryIdString); + Console.Error.WriteLine($"Error creating placeholder PST: {ex.Message}"); + return; } + } - // Perform bulk deletion of the collected messages. - if (entryIds.Count > 0) + // Ensure the directory for the result PST exists + try + { + string resultDirectory = Path.GetDirectoryName(resultPstPath); + if (!string.IsNullOrEmpty(resultDirectory) && !Directory.Exists(resultDirectory)) { - inbox.DeleteChildItems(entryIds); - Console.WriteLine($"Deleted {entryIds.Count} messages from the Inbox."); + Directory.CreateDirectory(resultDirectory); } - else + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error preparing output directory: {ex.Message}"); + return; + } + + // Open the source PST for read/write operations + try + { + using (PersonalStorage pst = PersonalStorage.FromFile(sourcePstPath)) { - Console.WriteLine("No messages found to delete."); + if (!pst.CanWrite) + { + Console.Error.WriteLine("The PST file is read‑only and cannot be modified."); + return; + } + + // Recursively delete all messages from the root folder and its subfolders + DeleteAllMessagesInFolder(pst.RootFolder); } } + catch (Exception ex) + { + Console.Error.WriteLine($"Error processing PST file: {ex.Message}"); + return; + } + + // Copy the modified PST to the result path + try + { + File.Copy(sourcePstPath, resultPstPath, true); + Console.WriteLine($"All messages have been removed. Modified PST saved to '{resultPstPath}'."); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error saving modified PST: {ex.Message}"); + } } catch (Exception ex) { - // Output any unexpected errors. - Console.Error.WriteLine($"Error: {ex.Message}"); + Console.Error.WriteLine($"Unexpected error: {ex.Message}"); + } + } + + // Deletes all messages within the specified folder and processes its subfolders + private static void DeleteAllMessagesInFolder(FolderInfo folder) + { + // Collect entry IDs of all messages in the current folder + List messageEntryIds = new List(); + foreach (MessageInfo messageInfo in folder.EnumerateMessages()) + { + if (!string.IsNullOrEmpty(messageInfo.EntryIdString)) + { + messageEntryIds.Add(messageInfo.EntryIdString); + } + } + + // Delete the collected messages in bulk, if any exist + if (messageEntryIds.Count > 0) + { + try + { + folder.DeleteChildItems(messageEntryIds); + Console.WriteLine($"Deleted {messageEntryIds.Count} messages from folder '{folder.DisplayName}'."); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error deleting messages from folder '{folder.DisplayName}': {ex.Message}"); + } + } + + // Recursively process subfolders + foreach (FolderInfo subFolder in folder.GetSubFolders()) + { + DeleteAllMessagesInFolder(subFolder); } } } diff --git a/working-with-outlook-storage-files/implement-functionality-to-delete-specific-messages-folders-or-other-items-from-outlook-pst-storage-files-via-the-pst-format.cs b/working-with-outlook-storage-files/implement-functionality-to-delete-specific-messages-folders-or-other-items-from-outlook-pst-storage-files-via-the-pst-format.cs index 4cc146f0..d4f9382e 100644 --- a/working-with-outlook-storage-files/implement-functionality-to-delete-specific-messages-folders-or-other-items-from-outlook-pst-storage-files-via-the-pst-format.cs +++ b/working-with-outlook-storage-files/implement-functionality-to-delete-specific-messages-folders-or-other-items-from-outlook-pst-storage-files-via-the-pst-format.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Collections.Generic; using Aspose.Email; using Aspose.Email.Storage.Pst; using Aspose.Email.Mapi; @@ -18,10 +17,9 @@ static void Main() { try { - using (PersonalStorage.Create(pstPath, FileFormatVersion.Unicode)) - { - // Empty PST created - } + // Create a new Unicode PST file + PersonalStorage.Create(pstPath, FileFormatVersion.Unicode).Dispose(); + Console.WriteLine($"Created placeholder PST file at '{pstPath}'."); } catch (Exception ex) { @@ -30,53 +28,26 @@ static void Main() } } - // Open PST with write access - using (PersonalStorage pst = PersonalStorage.FromFile(pstPath, true)) + // Open the PST file with write access + try { - // Delete a specific folder named "OldFolder" if it exists - try - { - FolderInfo oldFolder = pst.RootFolder.GetSubFolder("OldFolder"); - if (oldFolder != null) - { - // Delete the folder using its entry ID string - pst.DeleteItem(oldFolder.EntryIdString); - Console.WriteLine("Folder 'OldFolder' deleted."); - } - } - catch (Exception ex) + using (PersonalStorage pst = PersonalStorage.FromFile(pstPath, true)) { - Console.Error.WriteLine($"Error deleting folder: {ex.Message}"); - } + // Add a test message to the root folder + MapiMessage testMessage = new MapiMessage("sender@example.com", "recipient@example.com", "Test Subject", "Test Body"); + string entryId = pst.RootFolder.AddMessage(testMessage); + Console.WriteLine($"Added message with EntryId: {entryId}"); - // Delete a specific message with subject "DeleteMe" from Inbox - try - { - FolderInfo inbox = pst.GetPredefinedFolder(StandardIpmFolder.Inbox); - if (inbox != null) - { - List messagesToDelete = new List(); - foreach (MessageInfo msgInfo in inbox.EnumerateMessages()) - { - if (msgInfo.Subject != null && msgInfo.Subject.Equals("DeleteMe", StringComparison.OrdinalIgnoreCase)) - { - messagesToDelete.Add(msgInfo.EntryIdString); - } - } - - if (messagesToDelete.Count > 0) - { - // Delete messages using their entry ID strings - inbox.DeleteChildItems(messagesToDelete); - Console.WriteLine($"{messagesToDelete.Count} message(s) with subject 'DeleteMe' deleted."); - } - } - } - catch (Exception ex) - { - Console.Error.WriteLine($"Error deleting messages: {ex.Message}"); + // Delete the previously added message + pst.DeleteItem(entryId); + Console.WriteLine($"Deleted message with EntryId: {entryId}"); } } + catch (Exception ex) + { + Console.Error.WriteLine($"Error processing PST file: {ex.Message}"); + return; + } } catch (Exception ex) { diff --git a/working-with-pop3-client/agents.md b/working-with-pop3-client/agents.md index c2922efb..8ae90a1d 100644 --- a/working-with-pop3-client/agents.md +++ b/working-with-pop3-client/agents.md @@ -83,5 +83,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/working-with-smtp-client/agents.md b/working-with-smtp-client/agents.md index a0c2e7c8..6f85a414 100644 --- a/working-with-smtp-client/agents.md +++ b/working-with-smtp-client/agents.md @@ -54,5 +54,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file diff --git a/zimbra/agents.md b/zimbra/agents.md index bede19f6..92dcb05c 100644 --- a/zimbra/agents.md +++ b/zimbra/agents.md @@ -56,5 +56,5 @@ See the root [agents.md](../agents.md) for repository-wide conventions. | Date | Run ID | Branch/Commit | |------|--------|---------------| -| 2026-04-01 | `20260401_045820` | [examples/batch-20260401_045820](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260401_045820) | +| 2026-04-02 | `20260402_140217` | [examples/batch-20260402_140217](https://github.com/aspose-email/agentic-net-examples/tree/examples/batch-20260402_140217) | \ No newline at end of file