Send attachments with drupal_mail
There might be other ways, but I have found that mailsystem and mimemail modules have to be installed to send email with attachment. So install these two modules first.

Then implement hook_mail to pass attachment to $message

/**
 * Implements hook_mail().
 */
function mymodule_mail($key, &amp;$message, $params) {
  $message['subject'] = $params['subject'];
  $message['body'][] = $params['body'];

  // Add attachment when available.
  if (isset($params['attachment'])) {
    $message['params']['attachments'][] = $params['attachment'];
  }
}


There are two ways to add attachment, you can either pass filecontent or filepath when adding an unmanaged file as attachment (not recorded in DB) or pass file object when adding an managed file.

When adding unmanaged file:

$attachment = array(
  'filepath' =&gt; $filepath, // or $uri
);


or

$attachment = array(
  'filecontent' =&gt; file_get_contents($uri),
  'filename' =&gt; $filename,
  'filemime' =&gt; 'application/pdf'
);


By using filecontent way, you probably will get two php errors by Jan 08, 2015 including


Warning: is_file() expects a valid path
Warning: realpath() expects parameter 1 to be a valid path


When adding managed file:

$attachment = file_load($fid);


Then send email by:

$params = array(
  'key' =&gt; 'my_email_template',
  'to' =&gt; 'test@example.com',
  'from' =&gt; 'test@example.com',
  'subject' =&gt; 'Test email',
  'body' =&gt; 'test',
  'attachment' =&gt; $attachment
);

drupal_mail('mymodule', $key, $to, $language, $params, $from);