I'm using VS2008 & C++ and I'm trying to create a command line program that sends an email.
I've looked on line and found some sample programs but none will compile for me.
Does anyone have an example program for me?
Thanks
This code compiles & runs for me - after figuring out the right headers etc. Still needs command line handling, and the use of the MAPI libraries is deprecated, but what do you want for free? Original code from codeproject.com
#include "windows.h"
#include "tchar.h"
#include "mapi.h"
#include "assert.h"
#define ASSERT assert
#define VERIFY assert
BOOL SendMail(CHAR *lpszFrom, CHAR *lpszTo, CHAR *lpszSubject, CHAR *lpszMessage)
{
BOOL bSent = FALSE;
HINSTANCE hMAPI = ::LoadLibrary(_T("mapi32.dll"));
if(0==hMAPI) return bSent;
typedef ULONG (FAR PASCAL *PFN_MAPILogon)(ULONG,LPTSTR,LPTSTR,FLAGS,ULONG,LPLHANDLE);
typedef ULONG (FAR PASCAL *PFN_MAPISendMail)(LHANDLE,ULONG,lpMapiMessage,FLAGS,ULONG);
typedef ULONG (FAR PASCAL *PFN_MAPILogoff)(LHANDLE,ULONG,FLAGS,ULONG);
PFN_MAPILogon MAPILogon = (PFN_MAPILogon)::GetProcAddress(hMAPI,"MAPILogon");
PFN_MAPISendMail MAPISendMail = (PFN_MAPISendMail)::GetProcAddress(hMAPI,"MAPISendMail");
PFN_MAPILogoff MAPILogoff = (PFN_MAPILogoff)::GetProcAddress(hMAPI,"MAPILogoff");
const BOOL bFunctionsLoaded = (0!=MAPILogon)&&(0!=MAPISendMail)&&(0!=MAPILogoff);
ASSERT(bFunctionsLoaded);
if(bFunctionsLoaded)
{
LHANDLE session = 0;
VERIFY(SUCCESS_SUCCESS==MAPILogon(0,0,0,MAPI_NEW_SESSION,0,&session));
ASSERT(0!=session);
MapiRecipDesc recipient;
::ZeroMemory(&recipient,sizeof(recipient));
recipient.ulRecipClass = MAPI_TO;
recipient.lpszName = lpszTo;
MapiMessage message;
::ZeroMemory(&message,sizeof(message));
message.lpszSubject = lpszSubject;
message.lpszNoteText = lpszMessage;
message.nRecipCount = 1;
message.lpRecips = &recipient;
bSent = SUCCESS_SUCCESS == MAPISendMail(session,0,&message,0,0);
VERIFY(SUCCESS_SUCCESS==MAPILogoff(session,0,0,0));
}
::FreeLibrary(hMAPI);
return bSent;
}
int _tmain(int argc, _TCHAR* argv[])
{
SendMail("from_you#go_daddy.com","to.someone#gmail.com","Test subject","New Message");
return 0;
}
Take a look at this: http://sourceforge.net/projects/blat/files/
Since your server is Exchange, your most convenient method to write a program to send email will be using C# and System.Net.Mail as demonstrated here. Here is the C++/CLI code:
static void CreateTestMessage2( String^ server )
{
String^ to = L"jane#contoso.com";
String^ from = L"ben#contoso.com";
MailMessage^ message = gcnew MailMessage( from,to );
message->Subject = L"Using the new SMTP client.";
message->Body = L"Using this new feature, you can send an e-mail message from an application very easily.";
SmtpClient^ client = gcnew SmtpClient( server );
// Credentials are necessary if the server requires the client
// to authenticate before it will send e-mail on the client's behalf.
client->UseDefaultCredentials = true;
client->Send( message );
client->~SmtpClient();
}
If you really want to use native C++ (ie. not access System.Net.Mail via C++/CLI) then you are stuck with one of the native APIs described here.
However you could use MapiSend or blat as described here.
Related
I'm trying to integrate Google's Crashpad into my application running on Ubuntu.
As per it's overview design
I create one handler process on ubuntu by following this link
Now for the client process, I should register it with the handler via a socket connection.
Linux/Android
On Linux, a registration is a connected socket pair between a client process and the Crashpad handler. This socket pair may be private or shared among many client processes.
How do I do that?
There is not much information available on internet related to crashpad. Can someone provide link to any working example
Unless you have a special use case that isn't listed here you shouldn't have to do anything with sockets manually. Just create a new instance of CrashpadClient at the entry point of your program and call StartHandler.
Here's a snippet from BugSplat's myUbuntuCrasher sample:
// Start crash handler
CrashpadClient *client = new CrashpadClient();
bool status = client->StartHandler(handler, reportsDir, metricsDir, url, annotations, arguments, true, false, attachments);
Here's the full example from main.cpp:
#include <stdio.h>
#include <unistd.h>
#include "client/crashpad_client.h"
#include "client/crash_report_database.h"
#include "client/settings.h"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#if defined(OS_POSIX)
typedef std::string StringType;
#elif defined(OS_WIN)
typedef std::wstring StringType;
#endif
using namespace base;
using namespace crashpad;
using namespace std;
bool initializeCrashpad(void);
StringType getExecutableDir(void);
void crash(void);
int main(int argc, char **argv) {
initializeCrashpad();
crash();
}
void crash() {
*(volatile int *)0 = 0;
}
bool initializeCrashpad() {
// Get directory where the exe lives so we can pass a full path to handler, reportsDir and metricsDir
StringType exeDir = getExecutableDir();
// Ensure that handler is shipped with your application
FilePath handler(exeDir + "/../crashpad/bin/crashpad_handler");
// Directory where reports will be saved. Important! Must be writable or crashpad_handler will crash.
FilePath reportsDir(exeDir);
// Directory where metrics will be saved. Important! Must be writable or crashpad_handler will crash.
FilePath metricsDir(exeDir);
// Configure url with BugSplat’s public fred database. Replace 'fred' with the name of your BugSplat database.
StringType url = "http://fred.bugsplat.com/post/bp/crash/crashpad.php";
// Metadata that will be posted to the server with the crash report map
map<StringType, StringType> annotations;
annotations["format"] = "minidump"; // Required: Crashpad setting to save crash as a minidump
annotations["database"] = "fred"; // Required: BugSplat database
annotations["product"] = "myUbuntuCrasher"; // Required: BugSplat appName
annotations["version"] = "1.0.0"; // Required: BugSplat appVersion
annotations["key"] = "Sample key"; // Optional: BugSplat key field
annotations["user"] = "fred#bugsplat.com"; // Optional: BugSplat user email
annotations["list_annotations"] = "Sample comment"; // Optional: BugSplat crash description
// Disable crashpad rate limiting so that all crashes have dmp files
vector<StringType> arguments;
arguments.push_back("--no-rate-limit");
// File paths of attachments to be uploaded with the minidump file at crash time - default bundle limit is 2MB
vector<FilePath> attachments;
FilePath attachment(exeDir + "/attachment.txt");
attachments.push_back(attachment);
// Initialize Crashpad database
unique_ptr<CrashReportDatabase> database = CrashReportDatabase::Initialize(reportsDir);
if (database == NULL) return false;
// Enable automated crash uploads
Settings *settings = database->GetSettings();
if (settings == NULL) return false;
settings->SetUploadsEnabled(true);
// Start crash handler
CrashpadClient *client = new CrashpadClient();
bool status = client->StartHandler(handler, reportsDir, metricsDir, url, annotations, arguments, true, false, attachments);
return status;
}
StringType getExecutableDir() {
char pBuf[FILENAME_MAX];
int len = sizeof(pBuf);
int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if (bytes >= 0) {
pBuf[bytes] = '\0';
}
char* lastForwardSlash = strrchr(&pBuf[0], '/');
if (lastForwardSlash == NULL) return NULL;
*lastForwardSlash = '\0';
return pBuf;
}
More information about configuring Crashpad in Ubuntu can be found here.
I'm adapting a tcp PubSub example to using inproc with multithread. It ends up hanging forever.
My setup
macOS Mojave, Xcode 10.3
zmq 4.3.2
The source code reeproducing the issue:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <thread>
#include "zmq.h"
void hello_pubsub_inproc() {
void* context = zmq_ctx_new();
void* publisher = zmq_socket(context, ZMQ_PUB);
printf("Starting server...\n");
int pub_conn = zmq_bind(publisher, "inproc://*:4040");
void* subscriber = zmq_socket(context, ZMQ_SUB);
printf("Collecting stock information from the server.\n");
int sub_conn = zmq_connect(subscriber, "inproc://localhost:4040");
sub_conn = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, 0, 0);
std::thread t_pub = std::thread([&]{
const char* companies[2] = {"Company1", "Company2"};
int count = 0;
for(;;) {
int which_company = count % 2;
int index = (int)strlen(companies[0]);
char update[12];
snprintf(update, sizeof update, "%s",
companies[which_company]);
zmq_msg_t message;
zmq_msg_init_size(&message, index);
memcpy(zmq_msg_data(&message), update, index);
zmq_msg_send(&message, publisher, 0);
zmq_msg_close(&message);
count++;
}
});
std::thread t_sub = std::thread([&]{
int i;
for(i = 0; i < 10; i++) {
zmq_msg_t reply;
zmq_msg_init(&reply);
zmq_msg_recv(&reply, subscriber, 0);
int length = (int)zmq_msg_size(&reply);
char* value = (char*)malloc(length);
memcpy(value, zmq_msg_data(&reply), length);
zmq_msg_close(&reply);
printf("%s\n", value);
free(value);
}
});
t_pub.join();
// Give publisher time to set up.
sleep(1);
t_sub.join();
zmq_close(subscriber);
zmq_close(publisher);
zmq_ctx_destroy(context);
}
int main (int argc, char const *argv[]) {
hello_pubsub_inproc();
return 0;
}
The result
Starting server...
Collecting stock information from the server.
I've also tried adding this before joining threads to no avail:
zmq_proxy(publisher, subscriber, NULL);
The workaround: Replacing inproc with tcp fixes it instantly. But shouldn't inproc target in-process usecases?
Quick research tells me that it couldn't have been the order of bind vs. connect, since that problem is fixed in my zmq version.
The example below somehow tells me I don't have a missing shared-context issue, because it uses none:
ZeroMQ Subscribers not receiving message from Publisher over an inproc: transport class
I read from the Guide in the section Signaling Between Threads (PAIR Sockets) that
You can use PUB for the sender and SUB for the receiver. This will correctly deliver your messages exactly as you sent them and PUB does not distribute as PUSH or DEALER do. However, you need to configure the subscriber with an empty subscription, which is annoying.
What does it mean by an empty subscription?
Where am I doing wrong?
You can use PUB for the sender and SUB for the receiver. This will correctly deliver your messages exactly as you sent them and PUB does not distribute as PUSH or DEALER do. However, you need to configure the subscriber with an empty subscription, which is annoying.
Q : What does it mean by an empty subscription?
This means to set ( configure ) a subscription, driving a Topic-list message-delivery filtering, using an empty subscription string.
Q : Where am I doing wrong?
Here :
// sub_conn = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, 0, 0); // Wrong
sub_conn = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "",0); // Empty string
Doubts also here, about using a proper syntax and naming rules :
// int pub_conn = zmq_bind(publisher, "inproc://*:4040");
int pub_conn = zmq_bind(publisher, "inproc://<aStringWithNameMax256Chars>");
as inproc:// transport-class does not use any kind of external stack, but maps the AccessPoint's I/O(s) onto 1+ memory-locations ( a stack-less, I/O-thread not requiring transport-class ).
Given this, there is nothing like "<address>:<port#>" being interpreted by such (here missing) protocol, so the string-alike text gets used as-is for identifying which Memory-location are the message-data going to go into.
So, the "inproc://*:4040" does not get expanded, but used "literally" as a named inproc:// transport-class I/O-Memory-location identified as [*:4040] ( Next, asking a .connect()-method of .connect( "inproc://localhost:4040" ) will, and must do so, lexically miss the prepared Memory-location: ["*:4040"] as the strings do not match
So this ought fail to .connect() - error-handling might be silent, as since the versions +4.x there is not necessary to obey the historical requirement to first .bind() ( creating a "known" named-Memory-Location for inproc:// ) before one may call a .connect() to get it cross-connected with an "already existing" named-Memory-location, so the v4.0+ will most probably not raise any error on calling and creating a different .bind( "inproc://*:4040" ) landing-zone and next asking a non-matching .connect( "inproc://localhost:4040" ) ( which does not have a "previously prepared" landing-zone in an already existing named-Memory-location.
Please have a look at the following code:
#pragma once
using namespace System::IO::Ports;
using namespace System::Text::RegularExpressions;
using namespace System::Collections::Generic;
ref class SMS
{
public:
SMS(void);
void sendMessage();
private:
System::IO::Ports::SerialPort ^port;
};
And the cpp file
#include "StdAfx.h"
#include "SMS.h"
SMS::SMS(void)
{
//Initialize the Serial Port
port = gcnew System::IO::Ports::SerialPort();
port->PortName = "COM12";
port->BaudRate = 9600;
port->Parity = Parity::None;
port->DataBits = 8;
port->StopBits = StopBits::One;
port->Handshake = Handshake::RequestToSend;
port->DtrEnable = true;
port->RtsEnable = true;
port->NewLine = System::Environment::NewLine;
if(!port->IsOpen)
{
port->Open();
}
//Set message format
port->WriteLine("AT+CMGF=1");
//Turn off echo
port->WriteLine("ATE0");
//Set memory configurations
port->WriteLine("AT+CPMS=\"ME\",\"ME\",\"ME\"");
}
//This method will send the SMS
void SMS::sendMessage()
{
if(!port->IsOpen)
{
port->Open();
}
port->WriteLine("AT+CMGS=\"012121212\"");
port->WriteLine("Test Message From C#");
port->WriteLine(System::Convert::ToString((char)(26)));
port->Close();
}
I am trying to send SMS by accessing the dongle. The port is correct and the dongle also fine because it responded to my friend's code few hours back. What am I doing wrong here? Have I done anything incorrect with C++/CLI ? AT Commands?
try adding "CR" "LF" (Carriage Return and Line Feed characters) after each AT command, some GSM dongles (like SIM900) needem in order to work. I hope this helps
Regards
if for win32,..
prefer using
HFILE OpenFile(
LPCSTR lpFileName, // pointer to filename
LPOFSTRUCT lpReOpenBuff, // pointer to buffer for file information
UINT uStyle // action and attributes
);
with other events,...
if using SMS gateway with modem AT command capability, that's fine for direct read and write to COM port
if U using cell phone, many of this will not work. example nokia 6070, 3100 model group
best test it using hyperterminal.
I used CBuildre6 for
https://sites.google.com/site/xpressdms/rosegarden
cheer.
I want to send an e-mail using the mail client on the user's Windows computer. As far as I can tell from the net, MAPI is the way to go. However, after reading through the MSDN documentation, I find out that MAPI is quite vast, with no source code examples. And I have no need for 99% of the features, I just want to send an e-mail. How do I do this?
I have found examples here on SO and on the web, but they seem to rely on something called Simple MAPI, which Microsoft has apparently listed as obsolete: "The use of Simple MAPI is discouraged. It may be altered or unavailable in subsequent versions of Windows". So I don't want to use those functions.
I found a very good example here, but unfortunately it is for Windows CE and isn't fully compatible with the Win32 API. I managed to implement the code from that link until it got to where it attempts to open the drafts folder, the parameters to GetProps aren't compatible. Does anyone know where I can find a similar code example for PC? C++ prefered.
I have solved this by my own, with the help from various internet sources.
Official MSDN documentation
MAPIEx: Extended MAPI Wrapper
Once the code is properly tested & documented, I will try to post it here for future reference.
See Sending Email using MAPI - A COM DLL
[Edit]
I've used MAPI once and I'll post the code. I'm not sure if it's what you're looking for. This sends a message with optionally attached files ( but no body ).
Header:
#pragma once
class MailSender
{
public:
MailSender();
~MailSender();
void AddFile(LPCTSTR path, LPCTSTR name = NULL);
bool Send(HWND hWndParent, LPCTSTR szSubject = NULL);
private:
struct attachment { tstring path, name; };
vector<attachment> m_Files;
HMODULE m_hLib;
};
Cpp:
#include "stdafx.h"
#include "MySendMail.h"
#include <mapi.h>
MailSender::MailSender()
{
m_hLib = LoadLibrary(_T("MAPI32.DLL"));
}
MailSender::~MailSender()
{
FreeLibrary(m_hLib);
}
void MailSender::AddFile( LPCTSTR file, LPCTSTR name )
{
attachment a;
a.path = file;
if (!name)
a.name = PathFindFileName(file);
else
a.name = name;
m_Files.push_back(a);
}
bool MailSender::Send(HWND hWndParent, LPCTSTR szSubject)
{
if (!m_hLib)
return false;
LPMAPISENDMAIL SendMail;
SendMail = (LPMAPISENDMAIL) GetProcAddress(m_hLib, _T("MAPISendMail"));
if (!SendMail)
return false;
vector<MapiFileDesc> filedesc;
for (std::vector<attachment>::const_iterator ii = m_Files.begin(); ii!=m_Files.end(); ii++)
{
MapiFileDesc fileDesc;
ZeroMemory(&fileDesc, sizeof(fileDesc));
fileDesc.nPosition = (ULONG)-1;
fileDesc.lpszPathName = (LPTSTR) ii->path.c_str();
fileDesc.lpszFileName = (LPTSTR) ii->name.c_str();
filedesc.push_back(fileDesc);
}
tstring subject;
if (szSubject)
subject = szSubject;
else
{
for (std::vector<attachment>::const_iterator ii = m_Files.begin(); ii!=m_Files.end(); ii++)
{
subject += ii->name.c_str();
if (ii+1 != m_Files.end())
subject += ", ";
}
}
MapiMessage message;
ZeroMemory(&message, sizeof(message));
message.lpszSubject = (LPTSTR) subject.c_str();
message.nFileCount = filedesc.size();
message.lpFiles = &filedesc[0];
int nError = SendMail(0, (ULONG)hWndParent, &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
if (nError != SUCCESS_SUCCESS && nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE)
return false;
return true;
}
How i can use this >> System::Net::Mail; namespace in c++ console application?
Maybe im asking fool question but im new in cpp
please help
see msdn
static void CreateTestMessage2( String^ server )
{
String^ to = L"jane#contoso.com";
String^ from = L"ben#contoso.com";
MailMessage^ message = gcnew MailMessage( from,to );
message->Subject = L"Using the new SMTP client.";
message->Body = L"Using this new feature, you can send an e-mail message from an application very easily.";
SmtpClient^ client = gcnew SmtpClient( server );
// Credentials are necessary if the server requires the client
// to authenticate before it will send e-mail on the client's behalf.
client->UseDefaultCredentials = true;
client->Send( message );
client->~SmtpClient();
}