SSIS Send email from package that is off the domain - sql-server

I have a SSIS package that is deployed to server that is not on a domain but it is within our network perimeter. I would like to be able to send an email on package failure but being off the domain presents a challenge that I have not faced before.
Using a dummy gmail account is not acceptable to the business.
I would like to use the company SMTP server (mail.somecompany.com) but I do not know how to do this while off the domain. Can someone please tell me if this is possible and what steps I need to take.
Useful information:
SQL Server 2016
Project Deployment mode
Visual Studio 2015
Many thanks in advance.

You can use script task for sending mail.
This might can help you:
MailMessage Mymsg = new MailMessage();
SmtpClient smptserver = new SmtpClient();
System.Net.Mail.Attachment attach;
Mymsg.From = new MailAddress("aa#abc.com");
String Tolist = Convert.ToString("a#aa.com");
String CClist = Convert.ToString("a#xse.com");
String BCClist = Convert.ToString("ba#aas.com");
if (!String.IsNullOrEmpty(Tolist))
Mymsg.To.Add(Tolist);
if (!String.IsNullOrEmpty(CClist))
Mymsg.CC.Add(CClist);
if (!String.IsNullOrEmpty(BCClist))
Mymsg.Bcc.Add(BCClist);
Mymsg.Subject = "Subject!";
Mymsg.Body = "Hi, Your message!";
Mymsg.IsBodyHtml = true;
try
{
smptserver.Send(Mymsg);
Console.WriteLine("OK");
}
catch (System.Net.Mail.SmtpException ex)
{
Console.WriteLine(ex.StatusCode.ToString());
}
Dts.TaskResult = (int)ScriptResults.Success;
smptserver = null;
Mymsg = null;

Related

Send SSIS package failure notification to Outlook email using no credentials

I'm new to SSIS and would like to send an email notification when a package fails. I'm using script task with the following code:
#region Namespaces
using System;
using System.Net;
using System.Net.Mail;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
#endregion
public void Main()
{
// TODO: Add your code here
String SendMailFrom = Dts.Variables["EmailFrom"].Value.ToString();
String SendMailTo = Dts.Variables["EmailTo"].Value.ToString();
String SendMailSubject = Dts.Variables["EmailSubject"].Value.ToString();
String SendMailBody = Dts.Variables["EmailBody"].Value.ToString();
try
{
MailMessage email = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.office365.com");
// START
email.From = new MailAddress(SendMailFrom);
email.To.Add(SendMailTo);
email.Subject = SendMailSubject;
email.Body = SendMailBody;
//END
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential(SendMailFrom, "Password");
SmtpServer.EnableSsl = true;
SmtpServer.Send(email);
MessageBox.Show("Email was Successfully Sent ");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Dts.TaskResult = (int)ScriptResults.Success;
Dts.TaskResult = (int)ScriptResults.Success;
}
My first issue is that I can not get this task to work with my own credentials, I get error "System.IOException: Unable to read data from the transport connection: net_io_connection closed."
But even beyond that, I know its unwise to hardcode my own credentials into this script task which I want run by a SQL Agent Job. Is there a way to send this email without any credentials? I don't care where the email is from, only where it is sent to.
SSIS Send Email task has lots of limitations.
It was created long time ago to work with Microsoft Exchange. It even doesn't support emails in HTML format.
Instead of the following line:
SmtpServer.Credentials = new System.Net.NetworkCredential(SendMailFrom, "Password");
You can try the following:
SmtpServer.UseDefaultCredentials = true;
SmtpServer.Credentials = CredentialCache.DefaultNetworkCredentials;
I found the solution to my initial problem here
I was able to add the following line of code to run the script using my own credentials:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12
However still need to figure out a solution to running this script using sql agent job. Would there be credential issues if another user were to run the job?

Remotely update game content in Unity3d for WebGL [duplicate]

I am trying to connect to a MS SQL database through Unity. However, when I try to open a connection, I get an IOException: Connection lost.
I have imported System.Data.dll from Unity\Editor\Data\Mono\lib\mono\2.0. I am using the following code:
using UnityEngine;
using System.Collections;
using System.Data.Sql;
using System.Data.SqlClient;
public class SQL_Controller : MonoBehaviour {
string conString = "Server=myaddress.com,port;" +
"Database=databasename;" +
"User ID=username;" +
"Password=password;";
public string GetStringFromSQL()
{
LoadConfig();
string result = "";
SqlConnection connection = new SqlConnection(conString);
connection.Open();
Debug.Log(connection.State);
SqlCommand Command = connection.CreateCommand();
Command.CommandText = "select * from Artykuly2";
SqlDataReader ThisReader = Command.ExecuteReader();
while (ThisReader.Read())
{
result = ThisReader.GetString(0);
}
ThisReader.Close();
connection.Close();
return result;
}
}
This is the error I get:
IOException: Connection lost
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacketHeader ()
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacket ()
Mono.Data.Tds.Protocol.TdsComm.GetByte ()
Mono.Data.Tds.Protocol.Tds.ProcessSubPacket ()
Mono.Data.Tds.Protocol.Tds.NextResult ()
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Rethrow as TdsInternalException: Server closed the connection.
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Mono.Data.Tds.Protocol.Tds70.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
Mono.Data.Tds.Protocol.Tds80.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
Please disregard any security risks with this approach, I NEED to do this for testing, security will come later.
Thank you for your time.
Please disregard any security risks with this approach
Do not do it like this. It doesn't matter if security will come before or after. You will end of re-writing the whole code because the password is hard-coded in your application which can be decompiled and retrieved easily. Do the connection the correct way now so that you won't have to re-write the whole application.
Run your database command on your server with php, perl or whatever language you are comfortable with but this should be done on the server.
From Unity, use the WWW or UnityWebRequest class to communicate with that script and then, you will be able to send and receive information from Unity to the server. There are many examples out there. Even with this, you still need to implement your own security but this is much more better than what you have now.
You can also receive data multiple with json.
Below is a complete example from this Unity wiki. It shows how to interact with a database in Unity using php on the server side and Unity + C# on the client side.
Server Side:
Add score with PDO:
<?php
// Configuration
$hostname = 'localhot';
$username = 'yourusername';
$password = 'yourpassword';
$database = 'yourdatabase';
$secretKey = "mySecretKey"; // Change this value to match the value stored in the client javascript below
try {
$dbh = new PDO('mysql:host='. $hostname .';dbname='. $database, $username, $password);
} catch(PDOException $e) {
echo '<h1>An error has ocurred.</h1><pre>', $e->getMessage() ,'</pre>';
}
$realHash = md5($_GET['name'] . $_GET['score'] . $secretKey);
if($realHash == $hash) {
$sth = $dbh->prepare('INSERT INTO scores VALUES (null, :name, :score)');
try {
$sth->execute($_GET);
} catch(Exception $e) {
echo '<h1>An error has ocurred.</h1><pre>', $e->getMessage() ,'</pre>';
}
}
?>
Retrieve score with PDO:
<?php
// Configuration
$hostname = 'localhost';
$username = 'yourusername';
$password = 'yourpassword';
$database = 'yourdatabase';
try {
$dbh = new PDO('mysql:host='. $hostname .';dbname='. $database, $username, $password);
} catch(PDOException $e) {
echo '<h1>An error has occurred.</h1><pre>', $e->getMessage() ,'</pre>';
}
$sth = $dbh->query('SELECT * FROM scores ORDER BY score DESC LIMIT 5');
$sth->setFetchMode(PDO::FETCH_ASSOC);
$result = $sth->fetchAll();
if(count($result) > 0) {
foreach($result as $r) {
echo $r['name'], "\t", $r['score'], "\n";
}
}
?>
Enable cross domain policy on the server:
This file should be named "crossdomain.xml" and placed in the root of your web server. Unity requires that websites you want to access via a WWW Request have a cross domain policy.
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>
Client/Unity Side:
The client code from Unity connects to the server, interacts with PDO and adds or retrieves score depending on which function is called. This client code is slightly modified to compile with the latest Unity version.
private string secretKey = "mySecretKey"; // Edit this value and make sure it's the same as the one stored on the server
public string addScoreURL = "http://localhost/unity_test/addscore.php?"; //be sure to add a ? to your url
public string highscoreURL = "http://localhost/unity_test/display.php";
//Text to display the result on
public Text statusText;
void Start()
{
StartCoroutine(GetScores());
}
// remember to use StartCoroutine when calling this function!
IEnumerator PostScores(string name, int score)
{
//This connects to a server side php script that will add the name and score to a MySQL DB.
// Supply it with a string representing the players name and the players score.
string hash = Md5Sum(name + score + secretKey);
string post_url = addScoreURL + "name=" + WWW.EscapeURL(name) + "&score=" + score + "&hash=" + hash;
// Post the URL to the site and create a download object to get the result.
WWW hs_post = new WWW(post_url);
yield return hs_post; // Wait until the download is done
if (hs_post.error != null)
{
print("There was an error posting the high score: " + hs_post.error);
}
}
// Get the scores from the MySQL DB to display in a GUIText.
// remember to use StartCoroutine when calling this function!
IEnumerator GetScores()
{
statusText.text = "Loading Scores";
WWW hs_get = new WWW(highscoreURL);
yield return hs_get;
if (hs_get.error != null)
{
print("There was an error getting the high score: " + hs_get.error);
}
else
{
statusText.text = hs_get.text; // this is a GUIText that will display the scores in game.
}
}
public string Md5Sum(string strToEncrypt)
{
System.Text.UTF8Encoding ue = new System.Text.UTF8Encoding();
byte[] bytes = ue.GetBytes(strToEncrypt);
// encrypt bytes
System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hashBytes = md5.ComputeHash(bytes);
// Convert the encrypted bytes back to a string (base 16)
string hashString = "";
for (int i = 0; i < hashBytes.Length; i++)
{
hashString += System.Convert.ToString(hashBytes[i], 16).PadLeft(2, '0');
}
return hashString.PadLeft(32, '0');
}
This is just an example on how to properly do this. If you need to implement session feature and care about security, look into the OAuth 2.0 protocol. There should be existing libraries that will help get started with the OAuth protocol.
An alternative would be to create your own dedicated server in a command prompt to do your communication and connecting it to unity to Handel multiplayer and SQL communication. This way you can stick with it all being created in one language. But a pretty steep learning curve.
Unity is game engine.
so That's right what the answer says.
but, Some domains need to connect database directly.
You shouldn't do that access database directly in game domain.
Anyway, The problem is caused by NON-ENGLISH computer name.
I faced sort of following errors at before project.
IOException: Connection lost
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacketHeader ()
Mono.Data.Tds.Protocol.TdsComm.GetPhysicalPacket ()
Mono.Data.Tds.Protocol.TdsComm.GetByte ()
Mono.Data.Tds.Protocol.Tds.ProcessSubPacket ()
Mono.Data.Tds.Protocol.Tds.NextResult ()
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Rethrow as TdsInternalException: Server closed the connection.
Mono.Data.Tds.Protocol.Tds.SkipToEnd ()
Mono.Data.Tds.Protocol.Tds70.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
Mono.Data.Tds.Protocol.Tds80.Connect (Mono.Data.Tds.Protocol.TdsConnectionParameters connectionParameters)
And after changing computer name as ENGLISH, It works.
I don't know how it's going. But It works.
Mono's System.Data.dll has some issues in P.C has NON-ENGLISH Computer name.
So, at least Unity project.
You should tell your customer Do not set their computer name as NON-ENGLISH.
I don't know people in mono knows these issue or not.
---------- It's OK in after 2018 version ----------
Api Compatibility Level > .Net 4.x
You can connect database in Non-english computer name machine.

SMTP Connection for SSIS 2008

I am new to SSIS and trying to figure out a way to set up a SMTP connection for an email. I did some online research about this but didn't find a clear explanation on how set up a smtp connection. Can I use outlook 2013 to send an email from SSIS? If yes then how do I create a new smtp connection using outlook 2013
I am trying to send an email from ssis with the ID like donotreply#abc.com
Here i used System.Net.Mail assembly to send email notification.
Add a script task in your SSIS package and include this code provided that your smtp server is working.
private void SendMail(
string sendTo,
string from,
string subject,
string body,
bool isBodyHtml,
string SMTPServer,
string userName,
string password,
string domain,
string attachments,
string sendCC)
{
System.Net.Mail.MailMessage oMessage = default(System.Net.Mail.MailMessage);
System.Net.Mail.SmtpClient mySmtpClient = default(System.Net.Mail.SmtpClient);
oMessage = new System.Net.Mail.MailMessage(from, sendTo, subject, body);
oMessage.CC.Add(sendCC);
oMessage.IsBodyHtml = isBodyHtml;
mySmtpClient = new System.Net.Mail.SmtpClient(SMTPServer, 25);
if (string.IsNullOrEmpty(userName))
{
mySmtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
}
else
{
mySmtpClient.Credentials = new System.Net.NetworkCredential(userName, password, domain);
}
mySmtpClient.Send(oMessage);
}

How to synchronize merge subscription in Sql Compact DB (on a Mobile device emulator)

Using SQL ManagementStudio 2008 I created SQL 3.5 Compact DB (TestCompact.sdf) and I have created subscription to existing Publication. Using SQL Management Studio it is working. I have transfered TestCompact.sdf to Windows Mobile 5 emulator device and with QueryAnalyzer for Mobile I could query existing tables in TestCompact.sdf. I don't know how to start replication synchronization on that mobile device. Do I need to write some C# code or it is possible do it more simple?
EDIT: (Added after reply on my question)
Maybe it will be useful for someone what C# code did the job for me:
(Using SQL Management Studio - Properties on existing subscription for my Compact DB) I read what are values for a replObj properties)
private void btnSync_Click(object sender, EventArgs e)
{
SqlCeConnection sqlCeConn = null;
SqlCeReplication replObj = new SqlCeReplication();
string connString = #"data source=\My Documents\TestReplicationCompactDB.sdf;Password=bero";
replObj.InternetUrl = #"http://192.168.99.99/VirtualDirectoryForCompactDBReplication/sqlcesa35.dll";;
replObj.PublisherDatabase = "TestReplicationDB";
replObj.PublisherSecurityMode = SecurityType.NTAuthentication;;
replObj.Publisher = #"DBTESTSRV\SQL2008";
replObj.Publication = "TestReplication2";
replObj.Subscriber = "TestReplication";
replObj.SubscriberConnectionString = #"data source=\My Documents\TestReplicationCompactDB.sdf;Password=bero";
replObj.InternetLogin = #"ares\intor";
replObj.InternetPassword = "intor";
try
{
sqlCeConn = new SqlCeConnection(connString);
sqlCeConn.Open();
replObj.Synchronize();
sqlCeConn.Close();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
if (sqlCeConn != null && sqlCeConn.State == ConnectionState.Open)
sqlCeConn.Close();
return;
}
string countPublisherChanges = replObj.PublisherChanges.ToString();
string countSubScriberChanges = replObj.SubscriberChanges.ToString();
MessageBox.Show(String.Format("Finished with {0} subscriber changes and with {1} publisher changes", countSubScriberChanges, countPublisherChanges));
}
You need to write "some" C# code, at the end of the Wizard in SSMS you get some sample code.

How to send email from windows form app with log4net

I have set up log4net in my C# 3.5 windows form application. I am looking for how to send email from a client pc with log4net. The SMTPAppender requires knowledge of SMTPHost and the examples I've seen are for web applications.
Is there a way to send email from an application that will work on any client's computer that may or may not be in a domain or network. I guess I would also need to be able to check if there is a connection available.
I've searched for an answer but I don't have much experience programming with email or the web to know what to look for. Any ideas to steer me in the right direction?
c# SmtpClient is quite right for your needs. here's some sample code (host is an ip address or host name, and the port is usually 25, but not necessarily) :
public static void SendMail(
string host,
int port,
SmtpAuthentication authentication,
string userName,
string password,
string from,
string to,
string cc,
string subject,
string body,
string[] attachments)
{
// Create and configure the smtp client
SmtpClient smtpClient = new SmtpClient();
if (host != null && host.Length > 0)
{
smtpClient.Host = host;
}
smtpClient.Port = port;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
if (authentication == SmtpAuthentication.Basic)
{
// Perform basic authentication
smtpClient.Credentials = new System.Net.NetworkCredential(userName, password);
}
else if (authentication == SmtpAuthentication.Ntlm)
{
// Perform integrated authentication (NTLM)
smtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
}
MailMessage mailMessage = new MailMessage();
mailMessage.Body = body;
mailMessage.From = new MailAddress(from);
mailMessage.To.Add(to);
mailMessage.CC.Add(cc);
foreach (string attachement in attachments)
{
mailMessage.Attachments.Add(new Attachment(attachement));
}
mailMessage.Subject = subject;
mailMessage.Priority = MailPriority.Normal;
smtpClient.Send(mailMessage);
}
}

Resources