SQLの窓

2018年10月09日


C# : VB.net : SQLExpress(SQLServer) : SQL-DMO と同等の SMO によるバックアップ

SQL-DMO は、COM なので主に VBScript から使われていましたが、SMO は、SQL-DMO に取って代わる Framework ベースの API です。もともとが巨大なクラスの集合体なので、バックアップにしか通常使う事がありませんが、SQLServer の運用を行うなら知っておく必要はあります

バックアップは SQL からも出来、そちらのほうが簡単です。SQL-DMO や SMO は、テープによるデータのバックアップを想定しており、デバイスを作成しても実体は作成されません。ディスクファイルでも、追加でバックアップされます

バックアップ後の内容の確認は以下のようにして行います
RESTORE FILELISTONLY FROM DISK = 'C:\tmp\backup.dmp'
参照としては以下の5つを追加します 1) Microsoft.SqlServer.ConnectionInfo 2) Microsoft.SqlServer.Management.Sdk.Sfc 3) Microsoft.SqlServer.Smo 4) Microsoft.SqlServer.SmoExtended 5) Microsoft.SqlServer.SqlEnum SMO ライブラリのダウンロードは nuget.exe が簡単です。 nuget.exe をダウンロードして専用のフォルダで実行します。
nuget install Microsoft.SqlServer.SqlManagementObjects -Version 140.17283.0
※ バージョン選択の参考ページ nuget.exe と同じ場所に、Microsoft.SqlServer.SqlManagementObjects.140.17283.0 フォルダが作成されるので、lib\net40 内から dll を参照して使用します。 ▼ C#
// サーバー
Server srv;
// インスタンス
srv = new Server();

// サーバーインスタンスの情報
srv.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect;
srv.ConnectionContext.LoginSecure = false;
srv.ConnectionContext.Login = "sa";
srv.ConnectionContext.Password = "パスワード";
// 接続
srv.ConnectionContext.Connect();

// バージョンの表示
Console.WriteLine(srv.Information.Version);

// デバイスオブジェクト
BackupDevice backup_dev = new BackupDevice();

// サーバーと関係付ける
backup_dev.Parent = srv;
// 論理名を設定
backup_dev.Name = "BACKUP";
// 装置のタイプ
backup_dev.BackupDeviceType = BackupDeviceType.Disk;
// 実際の場所( バックアップするまで作成されません )
backup_dev.PhysicalLocation = @"c:\tmp\backup.dmp";

// 処理サンプルとして一旦削除して作成する
if (srv.BackupDevices["BACKUP"].State == SqlSmoState.Existing)
{
	srv.BackupDevices["BACKUP"].Drop();
	backup_dev.Create();
}

// バックアップオブジェクト
Backup dbBackup = new Backup();

// デフォルトは Database
dbBackup.Action = BackupActionType.Database;
dbBackup.Database = "lightbox";
dbBackup.Devices.AddDevice("BACKUP", DeviceType.LogicalDevice);
dbBackup.BackupSetName = "BACKUP_lightbox";

// バックアップ開始
dbBackup.SqlBackup(srv);

// 接続解除
srv.ConnectionContext.Disconnect();

Console.WriteLine("バックアップが終了しました");

▼ VB.net
' サーバー
Dim srv As Server
' インスタンス
srv = New Server()

' サーバーインスタンスの情報
srv.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect
srv.ConnectionContext.LoginSecure = False
srv.ConnectionContext.Login = "sa"
srv.ConnectionContext.Password = "パスワード"
' 接続
srv.ConnectionContext.Connect()

' バージョンの表示
Console.WriteLine(srv.Information.Version)

' デバイスオブジェクト
Dim backup_dev As BackupDevice = New BackupDevice()

' サーバーと関係付ける
backup_dev.Parent = srv
' 論理名を設定
backup_dev.Name = "BACKUP"
' 装置のタイプ
backup_dev.BackupDeviceType = BackupDeviceType.Disk
' 実際の場所( バックアップするまで作成されません )
backup_dev.PhysicalLocation = "c:\tmp\backup.dmp"
Try
	' 既に存在する場合はそのまま使う
	backup_dev.Create()
Catch ex As Exception
End Try


' バックアップオブジェクト
Dim dbBackup As Backup = New Backup()

' デフォルトは Database
dbBackup.Action = BackupActionType.Database
dbBackup.Database = "lightbox"
dbBackup.Devices.AddDevice("BACKUP", DeviceType.LogicalDevice)
dbBackup.BackupSetName = "BACKUP_lightbox"

' バックアップ開始
dbBackup.SqlBackup(srv)

' 接続解除
srv.ConnectionContext.Disconnect()

Console.WriteLine("バックアップが終了しました")

関連する記事

SQLServer : SQLでバックアップ
SQL-DMO による VBScriptによるバックアップ

関連するMicrosoft のリンク

SMO クラス ライブラリ
SQL-DMO のインストール( SQLServer2005_BC.msi )



【SQLExpressの最新記事】
posted by lightbox at 2018-10-09 15:40 | SQLExpress | このブログの読者になる | 更新情報をチェックする

2018年10月07日


さくらインターネットに Ruby をインストールして mechanize ( 先に nokogiri のインストールが必要でした )

現時点でインストールできた最も新しいバージョンは、2.4.4 でした
 
  2.3.0
  2.3.1
  2.3.2
  2.3.3
  2.3.4
  2.3.5
  2.3.6
  2.3.7
  2.4.0-dev
  2.4.0-preview1
  2.4.0-preview2
  2.4.0-preview3
  2.4.0-rc1
  2.4.0
  2.4.1
  2.4.2
  2.4.3
  2.4.4
  2.5.0-dev
  2.5.0-preview1
  2.5.0-rc1
  2.5.0
  2.5.1
  2.6.0-dev
  2.6.0-preview1
  2.6.0-preview2
2.5.0 と 2.5.1 は、BUILD FAILED となります インストール方法の参考は、『さくらレンタルサーバーにRubyをインストールする(2015-10-24)』 です。 ▼ .bashrc( 結局、local/bin と local/src は空です )
export RBENV_ROOT=$HOME/local/rbenv
export PATH=$RBENV_ROOT/bin:$HOME/local/bin:$PATH
eval "$(rbenv init -)"

export TMPDIR=$HOME/tmp

alias dir='ls -l'
参考通りに rbenv global 2.4.4 実行後、bundlerをインストールします。 bundler インストール時に『WARNING: Unable to pull data from 'https://rubygems.org/': SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: tlsv1 alert protocol version (https://api.rubygems.org/specs.4.8.gz)』と出ますが、インストールは完了します。 エラーが出る場合
gem install bundler --source http://rubygems.org と実行してみて下さい。

以降で install エラーが出る場合は、

gem sources --remove https://rubygems.org/ を実行してから 
gem sources --add http://rubygems.org で http を登録します

確認は gem sources
gem install mechanize インストールは失敗しますが、表示中に『gem install pkg-config -v "~> 1.1"』とあるので実行してインストールします。その後、 gem install nokogiri -- --use-system-libraries を実行します。 『参考 : Installing Nokogiri』 最後に、『gem install mechanize』を実行して完了です。 テスト結果 Wndows10 上の Ruby + mechanize では、C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/net-http-persistent-3.0.0/lib/net/http/persistent.rb を以下のリンク先のように変更する必要がありました。 Sets a default pool size for Windows as Process::RLIMIT_NOFILE is not supported さくらインターネット上の mechanize では、どうも思ったような結果が得られないので、インストールができても使えるとは限りません。( どうも SSL のワーニングが関係しているかもしれません。http でアクセスできる場所が動作しますが、https では動作しません )
posted by lightbox at 2018-10-07 00:00 | Ruby 2018 | このブログの読者になる | 更新情報をチェックする

2018年09月09日


WordPress のテーマのテンプレート

wp-content/themes にフォルダを作成して、その中に最低限必要なのが、style.cssindex.php です。

0) index.php
( ここで使用しているテンプレートで、テンプレート階層の最下層です )

単純なサイトならばこれだけでもなんとかなりますが、これ以外に以下の部品を用意するだけで、WordPress のテーマの概要を掴む事ができます。

1) header.php
2) footer.php
3) content.php
( 1〜3 は、index.php から呼び出される部品です )

4) functions.php
( WordPress のオプションを設定したり、テーマで必要な関数を定義します / PHP で記述します )

style.css
@charset "UTF-8";
/*

Theme Name: テーマ名
Theme URI: テーマのサイトのURI
Author: 作者名
Author URI: 作者のサイトのURI
Description: 説明
Version: バージョン
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

*/


sryle.css は、もちろん css を記述して使用できますが、いろいろなバリエーションのページを作成する場合に必ずしもこのファイルにこだわる必要も無いので、ここでは単なる『テーマのラベル』として認識しておきます。

※ 自動的にこの style.css が必ず設置されるものでは無く、ここでは css は『テーマの構成』には関係ありません

この style.css の中にコメントとして書かれた内容のうち、『テーマ名』が、WordPress 管理画面の『テーマ』で表示されて『有効』にする事ができます



index.php

get_header()get_footer() は、後述の header.phpfooter.php で定義された内容を出力します。

wp_head() は、システムで定義済の ヘッダー部分に出力するべき内容を出力します。例えば、プラグインで登録されたアプリケーションにとって必要なものがここを経由して実装されます。

そして一番重要なのは、get_template_part() で、任意のテンプレートを使用する事ができるという事です。
ここでは、"content.php" が使用されます
<?php
/*

メインテンプレートファイル

これはWordPressのテーマで最も一般的なテンプレートファイルです
テーマに必要な2つのファイルの1つ(style.css)
これは、何も特定のクエリに一致しない場合にページを表示するために使用されます。

*/


get_header();
wp_head();
?>
</head>
<body>
<div id="root">
<h3>Main Template File</h3>
<?php

if ( have_posts() ) :

	// *****************************
	// 投稿がある間ループ
	// *****************************
	while ( have_posts() ) : 

		// *****************************
		// 次の投稿を取得
		// *****************************
		the_post();

		// *****************************
		// フォーマットを取得する
		// (通常は空文字列)
		// *****************************
		$get_post_format = get_post_format();
		print "<span>$get_post_format</span>";

		// *****************************
		// "content-{$get_post_format}.php" を使用
		// *****************************
		get_template_part( 'content', $get_post_format );

	endwhile;

else :
	// 投稿が無い場合に表示したい内容
endif;

?>

</div>
<?php get_footer(); ?>


header.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- ユーザヘッダー -->
<link rel="stylesheet" href="<?= get_stylesheet_uri() ?>" type="text/css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css">


HTML 上の <head> 〜 </head> の共通の部分という認識でいいと思います。
※ ここでは、意図的に style.css を記述しています。


footer.php
<!-- ユーザーフッター -->

</body>
</html>


HTML 上の コンテンツの下部にある共通の部分です。

content.php
<div id="post-<?php the_ID(); ?>">
<a href="<?= esc_url( get_permalink() ) ?>"><?= get_the_title() ?></a>

<?php

	the_content( ); 
?>
</div>


the_content( ) は、現在の投稿の本文を出力し、the_ID() は投稿の ID を出力し、get_permalink() と get_the_title() で投稿のタイトルに単独ページへのリンクを設定しています。

functions.php

システムに対して、オプション設定を行うファイルです。オプションを追加したり、デフォルトで追加されているものを削除したり、PHP として技術的な処理を行ったりします。

ここでは、冒頭でテーマ限定でエラー時にエラー出力をするように設定しています。

さらに、システムで定義済の『投稿フォーマット』を追加して、投稿時に選択できるようにしています。


( ここでは、content-gallery.php が無いので、content.php が使用されます )

<?php
// ***********************************************
// このテーマでエラーの場合表示
// ***********************************************
error_reporting( E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED & ~E_WARNING );
ini_set('display_errors', '1');

// ***********************************************
// 投稿フォーマットを追加
// ***********************************************
add_theme_support('post-formats', array( 'gallery' ));

// ▼ wp_head() から排除
remove_action( 'wp_head', 'wlwmanifest_link' );
remove_action( 'wp_head', 'wp_generator' );

// ***********************************************
// rsd_link は、general-template.php 内で定義
// ***********************************************
remove_action( 'wp_head', 'rsd_link' );


// ***********************************************
// emoji 関連削除
// ***********************************************
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );

// ***********************************************
// wp-json 削除
// https://developer.wordpress.org/reference/functions/rest_output_link_wp_head/
// ***********************************************
remove_action('wp_head','rest_output_link_wp_head');

// ***********************************************
// dns-prefetch 削除
// wp-includes/default-filters.php
// ***********************************************
remove_action('wp_head','wp_resource_hints',2);

// ***********************************************
// フィード 削除
// ***********************************************
remove_action('wp_head', 'feed_links_extra', 3);

// ***********************************************
// prev & next  削除
// ***********************************************
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');

// ***********************************************
// canonical 削除
// ***********************************************
remove_action('wp_head', 'rel_canonical');

// ***********************************************
// shortlink 削除
// ***********************************************
remove_action('wp_head', 'wp_shortlink_wp_head');

// ***********************************************
// oembed 削除
// ***********************************************
remove_action('wp_head','wp_oembed_add_discovery_links');
remove_action('wp_head','wp_oembed_add_host_js');

// ***********************************************
// 管理バー 削除
// ***********************************************
add_filter( 'show_admin_bar', '__return_false' );

?>


二つの投稿の表示結果

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- ユーザヘッダー -->
<link rel="stylesheet" href="http://ドメイン/lightbox/wp-content/themes/lightbox/style.css" type="text/css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css">





</head>
<body>
<div id="root">
<h3>Main Template File</h3>
<span>gallery</span><div id="post-35">
<a href="http://ドメイン/lightbox/template/2018/08/29/next-post/">ふたつめ</a>

<p>the_post_navigation の確認</p>
</div>
<span></span><div id="post-1">
<a href="http://ドメイン/lightbox/none/2018/08/29/hello-world/">Hello world!</a>

<p>WordPress へようこそ。これは最初の投稿です。編集もしくは削除してブログを始めてください !</p>
</div>

</div>
<!-- ユーザーフッター -->

</body>
</html>






posted by lightbox at 2018-09-09 21:22 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2018年09月04日


C# : DataGridView に TKMP.DLL の IMAP(POP3) で受信したメールを非同期に表示する( 添付ファイルも取得 )

※ BasicImapLogon => BasicPopLogon, ImapClient => PopClient で POP3 も同じです

DataGridView の作成方法の注意点は、『C# でDataTable と DataSource を使用して、DataGridView にデータを表示するテンプレート( 行をダブルクリックしてダイアログを表示して行データを処理 )』を参照して下さい

画面のテンプレートのダウンロード


行をダブルクリックすると、本文を表示します。ここでは、サンプルして行のカラムに本文を保存していますが、本来は外部に保存します。



▼ スプリットコンテナを使用していますが、配置方法は基本的に直感的なものと逆です。


※ 重要
Gmail では安全性の低いアプリの許可を『有効』にする必要があります
※ サーバーは imap.gmail.com
※ Yahoo! メールでは、接続はできるのですが、メールが取得できません ( imap.mail.yahoo.co.jp )。
※ BasicImapLogon => BasicPopLogon, ImapClient => PopClient に変更すると、Yahoo! で接続できました
( POP3 : pop.mail.yahoo.co.jp : 995 )

.NET用メール送受信クラスライブラリ (TKMP.DLL) 
※ 2018-06-20 時点で 3.1.8( 2017/02/15 作成 )



using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TKMP.Net;
using TKMP.Reader;

namespace MailRecTest
{
	public partial class Form1 : Form
	{
		// ******************************************************
		// 画面レイアウト作成方法は以下を参照
		// http://logicalerror.seesaa.net/article/459948736.html
		// ******************************************************

		private DataTable table;
		private DataColumn column;
		private DataRow row;

		private SynchronizationContext sc = null;
		private ImapClient client = null;
		private int mailCounter = 0;
		private string[] bodyText = new string[20];

		// 接続解除用
		private int endCounter = 0;
		private int maxCount = 20;

		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			// 非同期内からの UI スレッドへのアクセス用
			sc = SynchronizationContext.Current;

			this.toolStripStatusLabel1.Text = "ツールバーのボタンで受信してください";
		}

		private void toolStripButton1_Click(object sender, EventArgs e)
		{
			if (MessageBox.Show("メールを受信しますか?", "確認", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
			{
				return;
			}

			// IMAP 用基本認証
			BasicImapLogon logon = new BasicImapLogon("アカウント", "パスワード");
			// IMAP 用ログイン( 993 は、SSL 用 )
			ImapClient client = new ImapClient(logon, "サーバードメイン", 993);

			// SSL で接続する
			client.AuthenticationProtocol = AuthenticationProtocols.SSL;

			try
			{
				if (!client.Connect())
				{
					MessageBox.Show("接続できませんでした");
					return;
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show("接続エラーが発生しました");
				return;
			}

			// メールデータ一覧を格納するオブジェクト
			IMailData[] mailData = client.GetMailList();

			// データがありません
			if (mailData == null)
			{
				MessageBox.Show("データがありません");
				return;
			}

			// メールデータの数
			toolStripStatusLabel1.Text = mailData.Length.ToString();
			mailCounter = mailData.Length;
			if (mailCounter < maxCount)
			{
				maxCount = mailCounter;
			}

			// 読込み制限
			int idx = 0;


			// DataTable の作成
			table = new DataTable("TKMP");

			// 列情報 の作成
			column = new DataColumn();
			column.DataType = Type.GetType("System.String");
			column.ColumnName = "差出人";
			table.Columns.Add(column);

			// 列情報 の作成
			column = new DataColumn();
			column.DataType = Type.GetType("System.String");
			column.ColumnName = "件名";
			table.Columns.Add(column);

			// 列情報 の作成
			column = new DataColumn();
			column.DataType = Type.GetType("System.String");
			column.ColumnName = "受信日時";
			table.Columns.Add(column);

			// 列情報 の作成
			column = new DataColumn();
			column.DataType = Type.GetType("System.String");
			column.ColumnName = "本文";
			table.Columns.Add(column);

			// 非同期でメールデータを表示するループ
			foreach (var data in mailData)
			{

				idx++;
				if (idx > maxCount)
				{

					break;
				}

				// 個別にイベント登録
				data.BodyLoaded += new EventHandler(MailData_BodyLoaded);
				// 非同期処理の受信を一件づつ開始
				data.ReadBodyAnsync();

			}

		}

		private void MailData_BodyLoaded(object sender, EventArgs e) {


			IMailData MailData = (IMailData)sender;

			// 本文無し( 本文が必要な場合は、false で、reader.MainText )
			MailReader reader = new MailReader(MailData.DataStream, false);

			if (reader.FileCount == 0)
			{
				Console.WriteLine("添付ファイルはありません");
			}

			//添付ファイルのコレクションを検査します
			foreach (TKMP.Reader.File file in reader.FileCollection)
			{
				// 保存場所は事前に作成する必要があります
				// (メールとの関連は、アプリケーション側で工夫する必要があります)
				file.FileSave(@"c:\temp\data\");
			}
			//Console.WriteLine(reader.MainText);

			// UI スレッドへの処理( この場合、post_state は null )
			sc.Post((object post_state) =>
			{


				// 新規行
				row = table.NewRow();

				// 本文をメモリ内保存( 本来はファイルかデータベースに書きだす )
				row["本文"] = reader.MainText;

				// ヘッダの一覧より、目的のヘッダを探す
				foreach (TKMP.Reader.Header.HeaderString headerdata in reader.HeaderCollection)
				{

					if (headerdata.Name == "From")
					{
						row["差出人"] = headerdata.Data;
					}
					if (headerdata.Name == "Subject")
					{
						row["件名"] = headerdata.Data;
					}
					if (headerdata.Name == "Date")
					{
						Console.WriteLine(headerdata.Data);

						string target = headerdata.Data;
						target = target.Replace(" (JST)", "");
						target = target.Replace(" (PDT)", "");
						try
						{
							DateTime dt = System.DateTime.ParseExact(target, "ddd, d MMM yyyy HH':'mm':'ss zzz", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None);
							row["受信日時"] = string.Format("{0}", dt);
						}
						catch (Exception ex)
						{
							row["受信日時"] = headerdata.Data;
							Console.WriteLine("フォーマット変換できませんでした");
						}

					}

				}

				// 行を追加
				table.Rows.Add(row);


				// 接続解除用
				endCounter++;
				if (endCounter == maxCount)
				{

					endCounter = 0;

					// 受信終了
					client.Close();

					// データーソース経由で DataGridView を表示
					dataGridView1.DataSource = table;

					this.dataGridView1.Columns[3].Visible = false;

					// 第3カラム(受信日)で逆ソート
					dataGridView1.Sort(dataGridView1.Columns[2], ListSortDirection.Descending);
					// 自動整列
					dataGridView1.AutoResizeColumns();

				}


			}, null);

			// イベント削除
			MailData.BodyLoaded -= new EventHandler(MailData_BodyLoaded);


		}

		private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
		{
			int rowNumber = e.RowIndex;
			if (rowNumber < 0 ){
				return;
			}

			this.textBox1.Text = this.dataGridView1["本文",rowNumber].Value.ToString();
		}
	}
}


関連する記事

C# と VB.net : TKMP.DLL を使って IMAP でメール本文の一覧を取得する( コンソール )

C# : TKMP.DLLを使った、メール送信テンプレート



posted by lightbox at 2018-09-04 21:46 | VS(C#) | このブログの読者になる | 更新情報をチェックする

C# : TKMP.DLLを使った、メール送信テンプレート

C:\Users\ユーザ\Documents\Visual Studio 20XX\Templates\ProjectTemplates\Visual C# に保存して下さい


( TKMP.DLL 同梱 )

※ TKMP.DLL は 32ビット用です。





テンプレートが古いので、Microsoft の SMTP サーバーは pop-mail.outlook.com に変更して下さい

久しぶりにメールの処理の検証をしてみようと、最新(周辺)の Microsoft の Framework をチェックしてみたのですが、相変わらず標準的なものはなさそうなので、最新の TKMP.DLL で検証してみました。TKMP.DLL は運用はした事がありませんが、メール送信に非同期処理が無い事を除いて、たいていは間に合いそうな気がします。

しかし、いかに簡単に使えるように設計されていても、メール処理はそれなりに煩雑なので、単に『メール送信』に特化してクラスを作成しました。

メールは Hotmail でなくても使えますが、送信用のクラスを作成する為のテストに Hotmail を使って行い、Hotmail の特性に従ってエラー処理もしています。

Hotmail を使用する場合は、ひとつ注意が必要で、エラーになる原因としてメールサービスがスパム対策として確認用の画像を読ませてログインさせようとする場合があるようです。
MailClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TKMP.Writer;
using TKMP.Net;

namespace TKMP_SendMail_Sakura1 {
	class MailClass {
		private MailWriter mw = null;

		public string SmtpServer { get; set; }
		public int Port { get; set; }
		public string User { get; set; }
		public string Pass { get; set; }
		public AuthenticationProtocols Protocol { get; set; }

		private string err_message = "";

		public class MailClassErrorArg {
			public string Message { get; set; }
		}

		public delegate void MailClassError(MailClassErrorArg e);

		public bool SendMail(string To, string From, string Subject, string Body, string To_J, string From_J, MailClassError mce) {
			bool bResult = true;

			mw = new MailWriter();

			try {
				mw.ToAddressList.Add(To);
			}
			catch (Exception ex) {
				bResult = false;
			}
			if (!bResult) {
				if (mce != null) {
					MailClassErrorArg e = new MailClassErrorArg() { Message = "宛先が正しくありません" };
					mce(e);
				}
				return bResult;
			}

			// From が未指定や正しくない文字列の場合
			try {
				mw.FromAddress = From;
			}
			catch (Exception ex) {
				// ユーザが正しければ、以下のように設定しても『ユーザ名 <メールアドレス>』に変換される
				mw.FromAddress = "______@hotmail.co.jp";
			}

			TextPart tp = new TextPart(Body);
			mw.MainPart = tp;

			if (To_J != null) {
				mw.Headers.Add("To", To_J + " <" + To + ">");
			}
			else {
				mw.Headers.Add("To", To);
			}
			if (From_J != null) {
				mw.Headers.Add("From", From_J + " <" + From + ">");
			}
			else {
				// Hotmail では、自動的に 『ユーザ名 <メールアドレス>』に変換される
				mw.Headers.Add("From", From);
			}

			mw.Headers.Add("Subject", Subject);
			mw.Headers.Add("X-Mailer", "TKMP Version 3.1.2");

			var logon = new TKMP.Net.AuthLogin(User, Pass);
			SmtpClient sc = new SmtpClient(SmtpServer, Port, logon);
			sc.AuthenticationProtocol = Protocol;

			try {
				if (!sc.Connect()) {
					err_message = "接続に失敗しました";
					bResult = false;
				}
				else {
					sc.SendMail(mw);
					sc.Close();
				}
			}
			catch (Exception ex) {
				err_message = ex.Message;
				bResult = false;
			}
			if (!bResult) {
				if (mce != null) {
					MailClassErrorArg e = new MailClassErrorArg() { Message = err_message };
					// このメソッドの引数である、ErrorHandler デリゲートを呼び出す
					mce(e);
				}
			}

			return bResult;
		}

		public bool SendMail(string To, string From, string Subject, string Body, string To_J, string From_J) {
			return SendMail(To, From, Subject, Body, To_J, From_J, null);
		}

		public bool SendMail(string To, string From, string Subject, string Body) {
			return SendMail(To, From, Subject, Body, null, null, null);
		}

	}

}

エラー処理は、引数にデリゲートを渡す仕様にしているので、Java の 引数へのインターフェイス渡しのような感じで『ラムダ式』を使ってその場で記述する事を想定しています。

これによって、細かいエラー情報が必要な場合は記述し、そうでない場合はオーバーロードされた引数の少ないメソッドを使って成功が失敗かだけをチェックすればいいようになっています。
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Mail;
using System.Net;
using TKMP.Writer;
using TKMP.Net;

namespace TKMP_SendMail3
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e)
		{

			MailClass mc = new MailClass()
			{
				SmtpServer = "smtp.live.com",
				Port = 587,
				User = "ユーザ名@hotmail.co.jp",
				Pass = "パスワード",
				Protocol = AuthenticationProtocols.TLS
			};

			var result = mc.SendMail(
				"宛先メールアドレス",
				"ユーザ名@hotmail.co.jp",
				this.subject.Text,
				this.body.Text,
				null,   // 必要な場合、宛先を日本語で
				null,   // 必要な場合、差出人を日本語で
				(MailClass.MailClassErrorArg _e) =>
				{
					this.error.Text = _e.Message;
				}
			);

			if (result)
			{
				MessageBox.Show("メールを送信しました");
			}

		}

	}
}

Hotmail の仕様に関しては、正式には 『Outlook.com の POP、IMAP、および SMTP の設定』というページにあります

IMAP サーバー名: imap-mail.outlook.com

IMAP ポート: 993

IMAP 暗号化方法: TLS

POP サーバー名: pop-mail.outlook.com

POP ポート: 995

POP 暗号化方法: TLS

SMTP サーバー名: smtp-mail.outlook.com

SMTP ポート: 587

SMTP 暗号化方法: STARTTLS
一般的にどこのメールサービスでも、TLS または SSL と書かれていますが、TLS で 587、SSL で 465 です。( このへんはかなり仕様がわかり難いです / Microsoft は、TLS のみ。Google は、両方。他は SSL のみだったり ) メッセージのソースの様子 ( ソースは GMail で確認するのが一番良さそうです )
From: =?iso-2022-jp?B?GyRCOjk9UD9NGyhCQg==?= <______@hotmail.co.jp>
To: =?iso-2022-jp?B?GyRCMDhAaBsoQkI=?= <______@gmail.com>
Date: Tue, 23 Jul 2013 20:10:15 +0900
MIME-Version: 1.0
Subject: =?iso-2022-jp?B?GyRCN29MPhsoQg==?=
X-Mailer: TKMP Version 3.1.2
Content-Type: text/plain; charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit

$BK\J8$N(B
$BFbMF(B

Gmail 用テンプレート

コードは同じですが、smtp サーバーが、『smtp.gmail.com(TLS/587)』になります。ユーザは、Hotmail ではメールアドレスでしたが、Gmail では、ユーザ名部分だけで認証します(メールアドレスでもOKなはずです)。

安全性の低いアプリの許可を『有効』にします

Nifty 用テンプレート

同様に、コードは同じです。smtp サーバーは、『smtp.nifty.com(SSL/465)』になります。ユーザは、NiftyID を使用したメールアドレスを使いますが、From では通常の別名を使用します。

Yahoo 用テンプレート

同様です。smtp サーバーは、『smtp.mail.yahoo.co.jp(SSL/465)』になります。アカウントは、「@yahoo.co.jpより前の部分」となります。

関連する記事

(C#) / VS2010 または VS2012 : TKMP.DLL(3.1.2 または 3.1.8)を使った、『さくらインターネット』用メール送信テンプレート

さくらインターネット用



C# : DataGridView に TKMP.DLL の IMAP(POP3) で受信したメールを非同期に表示する( 添付ファイルも取得 )



posted by lightbox at 2018-09-04 21:21 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2018年09月01日


PHP の関数で規定されているキャッシュコントロールの無効 : session_cache_limiter( 'nocache' )

session_start() を実行しないと有効にならないので、セッションが必要無い場合は header を直書きすればいいと思いますが、セッションを有効にしても損は無いので以下のようにとておくと簡単です。

session_cache_limiter
<?php
session_cache_limiter('nocache');
session_start();
?>


header を直接書くと以下のようになります
<?php
header( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header( "Pragma: no-cache" );
?>

▼ 以下は、Cache-Control の値についての解説です
HTTP キャッシュ
「no-store」はもっと単純です。返されたレスポンスのバージョンにかかわらず、ブラウザのキャッシュやすべての中間キャッシュはそのレスポンスを一切格納できません。たとえば、個人の機密データや銀行データが含まれているレスポンスなどです。ユーザーがこのアセットをリクエストするたびに、リクエストがサーバーに送信され、完全なレスポンスが毎回ダウンロードされます。
※ 一部引用
posted by lightbox at 2018-09-01 13:31 | PHP + 特記事項 | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり