PST Forge Documentation
PST Forge is a high-performance, cross-platform C++ library for creating Microsoft Outlook PST files programmatically. Unlike other libraries, it does not require Outlook to be installed and works on Windows, Linux, and macOS.
Features
- No Outlook Dependency: Generate PSTs on any server or client machine.
- Cross-Platform: Works on Windows (MSVC), Linux (GCC/Clang), and macOS.
- Comprehensive Item Support:
- Messages (Emails) with Rich Text/HTML bodies
- Calendar Events (Appointments, Meetings, Recurrence)
- Tasks (Status, Due Dates)
- Journal Entries
- Attachments: Full support for adding file attachments.
- Unicode Support: Full UTF-8 support for subjects, bodies, and filenames (including Emojis 🚀).
- Node.js Bindings: Native N-API bindings for using high-performance C++ from JavaScript.
Installation (Enterprise Edition)
C++ SDK
Include the static library and headers from your distribution package.
# CMakeList.txt
find_package(PSTWriter REQUIRED)
target_link_libraries(myapp PRIVATE PSTWriter::Static)Node.js Module
Install via your private registry or local tarball:
npm install @enterprise/pst-writerC++ Quick Start
Here's a complete example generating a PST with a folder and a message.
#include "pst_writer/pst_writer.hpp"
#include "pst_writer/message.hpp"
using namespace pst_writer;
int main() {
// 1. Initialize Writer
PSTWriter writer("output.pst", CompatibilityMode::Standard);
// 2. Create Folder
writer.createFolder("Inbox");
// 3. Create Message
Message msg;
msg.subject = "Hello World";
msg.body_plain = "This is a test message.";
msg.from_name = "PST Writer";
msg.from_email = "bot@example.com";
// Add Recipient
msg.recipients.push_back({"User", "user@example.com", RecipientType::To});
// Add Attachment (Binary Data)
std::string content = "Attachment content";
std::vector<uint8_t> data(content.begin(), content.end());
msg.attachments.push_back({"test.txt", data});
// 4. Add to PST & Close
writer.addMessage(msg, "Inbox");
writer.close();
return 0;
}C++ Class: PSTWriter
The main entry point for the library.
class PSTWriter {
public:
PSTWriter(const std::string& path, CompatibilityMode mode = CompatibilityMode::Simplified);
~PSTWriter();
// Folders
uint64_t createFolder(const std::string& name);
// Items
uint64_t addMessage(const Message& msg, const std::string& folder);
uint64_t addEvent(const CalendarEvent& evt, const std::vector<std::string>& path);
uint64_t addTask(const TaskItem& task, const std::vector<std::string>& path);
uint64_t addJournal(const JournalEntry& entry, const std::vector<std::string>& path);
// Utility
void compact(); // Flush buffers
void close(); // Finalize file
};C++ Data Structures
Message Struct
struct Message {
std::string subject;
std::string body_plain;
std::string body_html;
std::string from_name;
std::string from_email;
std::vector<Recipient> recipients;
std::vector<Attachment> attachments;
std::chrono::system_clock::time_point timestamp;
};CalendarEvent Struct
struct CalendarEvent {
std::string subject;
std::string location;
std::chrono::system_clock::time_point start_time;
std::chrono::system_clock::time_point end_time;
bool is_all_day;
BusyStatus busy_status; // Free, Tentative, Busy, OutOfOffice
MeetingStatus meeting_status;
RecurrencePattern recurrence;
};Node.js Quick Start
The Node.js API uses a Builder pattern for creating messages and events.
const { PstWriter, PstMessage, PstEvent } = require('pst-writer');
// 1. Initialize
const writer = new PstWriter("output.pst");
writer.createFolder("Inbox");
// 2. Build Message
const msg = new PstMessage();
msg.setSubject("Hello directly from Node");
msg.setBody("This is cool!");
msg.setSender("Node Bot", "bot@node.js");
msg.addRecipient("User", "user@example.com", 1); // 1=To, 2=Cc, 3=Bcc
// Add Attachment (File Path)
msg.addAttachment("image.png", "/path/to/image.png");
// 3. Write
writer.addMessage("Inbox", msg);
// 4. Build Event
const evt = new PstEvent();
evt.setSubject("Team Meeting");
evt.setStartTime(Date.now());
evt.setEndTime(Date.now() + 3600000); // +1 hour
evt.setLocation("Conference Room A");
writer.addEvent("Calendar", evt);
writer.close();Node.js Class: PstWriter
- new PstWriter(path): Create a new writer.
- createFolder(name): Create a top-level folder.
- addMessage(folderName, messageObj): Add a generic message.
- addEvent(folderPath, eventObj): Add a calendar event. Folder path string (e.g., "Calendar/Work").
- close(): Finalize the file.
Node.js Builders
These classes are used to construct items before adding them to the PST.
PstMessage API
- setSubject(string)
- setBody(string): Plain text body.
- setSender(name, email)
- addRecipient(name, email, type): Type: 1(To), 2(Cc), 3(Bcc).
- addAttachment(filename, filepath): Note: Takes a file path string, not binary data.
PstEvent API
- setStartTime(ms) / setEndTime(ms): Unix timestamp in milliseconds.
- setLocation(string)
- setAllDay(boolean)
- setRecurrence(type, interval, ...)
C# / .NET API
The library includes a P/Invoke wrapper for seamless integration with .NET applications. It follows the `IDisposable` pattern for automatic resource management.
using PSTWriter;
// 1. Initialize (IDisposable ensures resource cleanup)
using (var writer = new PstWriter("output.pst")) {
// 2. Create Structure
writer.CreateFolder("Inbox");
// 3. Create Message
using (var msg = new PstMessage()) {
msg.Subject = "Report from C#";
msg.Body = "Generated via .NET Core";
msg.SetSender("Service Account", "svc@domain.com");
// Add Recipient
msg.AddRecipient("Admin", "admin@domain.com", RecipientType.To);
// Add Attachment
msg.AddAttachment("log.txt", "C:\\logs\\daily.log");
// Write to PST
writer.AddMessage("Inbox", msg);
}
// 4. Create Calendar Event
using (var evt = new PstEvent()) {
evt.Subject = "Sync Meeting";
evt.StartTime = DateTime.UtcNow;
evt.EndTime = DateTime.UtcNow.AddHours(1);
evt.Location = "Virtual";
writer.AddEvent("Calendar", evt);
}
// Auto-closed on dispose, or explicit close:
writer.Close();
}Integration Patterns
PST Forge is built to fit into modern data pipelines.
Forensics & e-Discovery
Use the C++ API for maximum throughput when ingesting terabytes of raw disk blocks or email fragments. The thread-safe allocator allows you to run parallel scraping threads that feed a single `PSTWriter` instance.
Cloud Migration (Node.js)
For simple Glue logic, use the Node.js bindings. Connect to Google Workspace APIs or Microsoft Graph API using standard Node.js libraries, fetch emails as JSON/MIME, and pipe them directly into `PstWriter`.
Enterprise Archives (.NET)
Integrate with existing Exchange Server archival agents or SharePoint exporters using the C# bindings. The library compiles to a standard DLL that can be deployed alongside your compiled .NET binaries.
Unicode & Internationalization
The library fully supports UTF-8. You can use international characters and emojis in:
- Folder names: "收件箱"
- Subjects: "Hello 🌍"
- Body content
- Sender/Recipient names
Performance
For high-throughput applications, the C++ API offers addMessagesParallel to utilize multi-core processors for writing messages. The library also buffers writes intelligently to minimize disk I/O.