SQLの窓

2018年01月29日


JavaScript の内部コード文字列を SHIFT_JIS としてダウンロードさせる方法

SyntaxHighlighter カスタマイズ

SyntaxHighlighter のツールバーの右端のアイコンでファイルをダウンロードさせると、テキストのキャラクタセットは UTF-8 になります。通常はそれでもいいのですが、VBScript をダウンロードしてもらう場合は SHIFT_JIS である必要があるので、なんとかならないかと調べてみてすぐ見つけたのが

javascriptで文字コード変換

という Qiita の記事でした。その中で紹介されている ecl.js は、自分も以前使った事があったのですが、バイナリデータとして変換する目的では無いと記憶していました。ですが、一応記事の冒頭にあるコードでテストしてみましたがうまく行かず、Encoding.js のほうを使用して目的を達成しました。

Encoding.js

元々、バイナリの配列にデータを格納して変換しているので、文字列からの変換処理さえあればすぐ使えます。その関数は、Qiita の記事に既に紹介されていたのでとても簡単に実装する事ができました。

実装では、改行コードの扱いに留意して下さい。

サンプルコード
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
<script src="https://lightbox.sakura.ne.jp/homepage/js/encoding.js"></script>

<script>
var str2array = function(str) {
    var array = [],i,il=str.length;
    for(i=0;i<il;i++) array.push(str.charCodeAt(i));
    return array;
};
var str   = "あいうえお";
var array = str2array( str );
var sjis_array = Encoding.convert(array, "SJIS", "UNICODE");
var sjis_data = new Uint8Array(sjis_array);

saveAs(
	new Blob(
		[sjis_data]
		, {type: "text/csv;charset=shift_jis"}
	)
	, "shift_jis.txt"
);

</script>
※ テストはこちらから行えます(ここで copy してリンク先で貼り付けて実行して下さい)

関連する記事

ブラウザ上のテキストデータを名前を付けて保存できる FileSaver.js を使って、テーブルのデータを Excel で開ける事を想定した CSV にして PC に保存

ファイルを JavaScript から保存する FileSaver.js

FileSaver.js は saveAs メソッドを提供します。ダウンロードする必要は無く、cdnjs でホスティング されています。

Uint8Array


posted by lightbox at 2018-01-29 14:10 | Comment(0) | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする

ブラウザ上のテキストデータを名前を付けて保存できる FileSaver.js を使って、テーブルのデータを Excel で開ける事を想定した CSV にして PC に保存

デモページ



ダウンロードは必要ありません。cdnjs でホスティングされています。ただ、使い方がイマイチ解りにくいのが難点でした。GitHub の demo.js を読んで初めて使い方が解ります。

FileSaver.js は saveAs メソッドを提供します

テキストデータをダウンロードするには、ブラウザが一般的に提供する Blob クラスを使う必要があります。そのインスタンスを saveAs メソッドに引き渡して目的が達成されます。( canvas を使って画像も保存できますが、話がややこしくなるのでここでは触れていません / ※ canvas-toBlob.js が必要です )


ソースコード
$(function() {

	$("#getcsv").on( "click", function(){

		var csv = "";

		$("table").find("th").each(function( index ){
			if ( index != 0 ) {
				csv += ",";
			}
			csv += '"' + $(this).text() + '"';
		});
		csv += "\n";

		var cnt = 0;
		$("table").find("tr").each( function(){

			// TH の最初の一行は処理しない )
			if ( cnt > 0 ) {

				$(this).find("td").each(function( col_cnt ){
					if ( col_cnt != 0 ) {
						csv += ",";
					}

					if ( col_cnt == 0 ) {
					// Excel で文字列をそのまま取り込めるように( 例. 0001 を文字列として扱う )
						csv += "=\"" + $(this).text() + "\"";
					}
					else {
						csv += "\"" + $(this).text() + "\"";
					}
				});
				csv += "\n";
			}

			cnt++;

		} );

		// UTF-8 の CSV を化けずに Excel で開く為
		var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
		saveAs(
			new Blob(
				[bom,csv]
				, {type: "text/csv;charset=" + document.characterSet}
			)
			, "syain.csv"
		);

	} );

});

Excel で正しく表示する為に

ブラウザ上のデータは UTF-8 を想定しています。なのでそのまま単純に保存してしまうと、Excel が SHIFT_JIS を想定して読み込むので化けてしまいます。そこで、テキストの先頭に BOM をセットして、UTF-8 である事を Excel に知らせてやる必要があります。
2014-11-29 バージョンでは、自分で BOM を設定する必要がありましたが、2016-06-16 バージョンでは内部に auto_bom という処理があり、XML か text のタイプで キャラクタセットが utf-8 の場合は自動で BOM を追加してくれます。

BOM が必要ない場合は、第三引数(ファイル名の次)に true を指定するといいようになっています。
その他、"0001" という文字列をそのまま使えるように、="0001" という形で CSV のフィールドにセットしています。こうした状態で Excel に読み込むと、式の値が文字列であるようになります。Excel としてはかなり特殊な扱いのデータになりますが、Excel として保存してからあらためて .CSV として保存するとフィールドの値は単純な 0001 となります。 Uint8Array
posted by lightbox at 2018-01-29 14:08 | Comment(0) | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする

JavaScript のみで、SHIFT_JIS や EUC-JP を UrlEncode に近い Escapeする Escape Codec Library

オリジナルはVector からダウンロードできる事を確認しました。しかし、実際は ecl.js と Sleipnir の相性が悪い件について という記事があり、そちらで新しいものが配布されています。

とりあえずこちらにも用意しました。
ecl_new.txt

内容は単純に変換関数がグローバルに追加されます。
EscapeSJIS
UnescapeSJIS
EscapeEUCJP
UnescapeEUCJP
EscapeJIS7
UnescapeJIS7
EscapeJIS8
UnescapeJIS8
EscapeUnicode
UnescapeUnicode
EscapeUTF7
UnescapeUTF7
EscapeUTF8
UnescapeUTF8
EscapeUTF16LE
UnescapeUTF16LE

一つだけタイプを取得する関数が以下です。
GetEscapeCodeType
戻される文字列の種類

SJIS
EUCJP
JIS7
JIS8
Unicode
UTF8
UTF16LE

※ ソースコードを見た限りでは、UTF7はありませんでした

UrlEncode にするには、これをさらに、
1) * から %24 に変換
2) + から %2B に変換
3) / から %2F に変換
してやる必要があります
※ 正確には、%20 を + に戻す必要がありますが、このままでもサーバでは正しく変換されます

関連する記事

javascriptで文字コード変換
( ここの情報は有益ですが、バイナリデータとしての変換は、ecl.js では出来ず、Encoding.js を使用します )



<script type="text/javascript" src="http://lightbox.on.coocan.jp/ecl_new.js" ></script>
<script type="text/javascript">
var str = EscapeUTF8(" !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
str = str.replace(/\//g,'%2F');
str = str.replace(/\*/g,'%24');
str = str.replace(/\+/g,'%2B');
str = str.replace(/%20/g,'+');
alert(str)
</script>

※ テストはこちらから行えます



posted by lightbox at 2018-01-29 13:30 | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする

2018年01月28日


WSH(VBScript) : 指定したキーでレジストリエディタを開く

今まで、コマンドプロンプトやエクスプローラから実行するのが一般的でしたが、Windows10 の PowerShell ウインドウからも実行できます( コマンドプロンプトと一応は同じです )



open_reg.vbs
ソースツールバーの右端のアイコンよりダウンロードできます
Set obj = Wscript.CreateObject("Shell.Application")
Dim strParam
if Wscript.Arguments.Count = 0 then
	' 引数が無い場合は、まずクリップボードを確認

	' クリップボード用
	' ※ HTA 等では直接 window.clipboardData より実行
	' ※ するように書き換える必要があります
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.Navigate("about:blank")
	Do While objIE.Busy
		' 100 ミリ秒
		Wscript.Sleep 100
	Loop
	strParam = objIE.document.parentWindow.clipboardData.GetData( "Text" ) & ""
	objIE.Quit

	strParam = Trim( strParam )
	' 無ければ入力
	if strParam = "" then
		strParam = InputBox("開く対象となるレジストリーのキーを入力して下さい","指定したキーでレジストリエディタを開く","HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft")
	end if

	' 管理者として実行を強制する
	obj.ShellExecute "wscript.exe", WScript.ScriptFullName & " runas """ & strParam & """", "", "runas", 1
	Wscript.Quit

else
	strParam = WScript.Arguments(0)
	if strParam <> "runas" then
		' 管理者として実行を強制する
		Set obj = Wscript.CreateObject("Shell.Application")
		if Wscript.Arguments.Count = 1 then
			obj.ShellExecute "wscript.exe", WScript.ScriptFullName & " runas """ & strParam & """", "", "runas", 1
			Wscript.Quit
		end if
	end if
end if


' 引数
strParam = WScript.Arguments(1)

strParam = Trim( strParam )

' レジストリ書き込み用
Set WshShell = CreateObject( "WScript.Shell" )
' WMI用
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

' レジストリエディタが最後に開いていたキーの登録を行います
strPath = "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey"
if GetOSVersion() >= 6 then
	strRegPath = "コンピュータ\" & strParam
else
	strRegPath = "マイ コンピュータ\" & strParam
end if

' 既に regedit が実行中の場合はいったん終了させます
Set colProcessList = objWMIService.ExecQuery _ 
	("Select * from Win32_Process Where Name = 'regedit.exe'") 
For Each objProcess in colProcessList
	' 最後のウインドウの位置とサイズを保存する為の終わらせ方
	WshShell.AppActivate("レジストリ エディタ")
	Wscript.Sleep(500)
	WshShell.SendKeys ("%{F4}")
	Wscript.Sleep(500)
	' 上記終わらせ方が失敗した時の強制終了
	on error resume next
	objProcess.Terminate() 
	on error goto 0
Next 

WshShell.RegWrite "HKCU\" & strPath, strRegPath, "REG_SZ"

' レジストリエディタを起動します
Call WshShell.Run( "regedit.exe" )
' レジストリエディタが終わるまで待つ場合は以下のようにします
' Call WshShell.Run( "regedit.exe", , True )

REM **********************************************************
REM OS バージョンの取得
REM **********************************************************
Function GetOSVersion()

	Dim colTarget,str,aData,I,nTarget

	Set colTarget = objWMIService.ExecQuery( _
		 "select Version from Win32_OperatingSystem" _
	)
	For Each objRow in colTarget
		str = objRow.Version
	Next

	aData = Split( str, "." )
	For I = 0 to Ubound( aData )
		if I > 1 then
			Exit For
		end if
		if I > 0 then
			nTarget = nTarget & "."
		end if
		nTarget = nTarget & aData(I)
	Next

	GetOSVersion = CDbl( nTarget )

End Function

ファイル名を指定、またはコマンドプロンプトから実行では、以下のようにします。
wscript.exe open_reg.vbs HKEY_CURRENT_USER\Console
クリップボードにキーがある場合は open_reg.vbs をそのままエクスプローラからダブルクリックします。 クリツプボードにデータが空の場合は、入力ダイアログを表示します(上記コードではデフォルトとして HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft を表示しています) 権限やセキュリティの関係でいろいろダイアログが表示されると事がほとんどです。 ▼ IE11 のクリップボード操作の制限 (IE の設定で、常に使用可能にする事もできます) また、これ以外にも、regedit.exe を実行する際に、管理者実行の確認がありますが、サンプルとして常に管理者権限で実行できるようにしています。。 管理者権限を取得しない単純コード
ソースツールバーの右端のアイコンよりダウンロードできます
Dim strParam

if Wscript.Arguments.Count = 0 then
	strParam = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName"
else
	strParam = WScript.Arguments(0)
end if



' レジストリ書き込み用
Set WshShell = CreateObject( "WScript.Shell" )
' WMI用
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

' レジストリエディタが最後に開いていたキーの登録を行います
strPath = "Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey"
if GetOSVersion() >= 6 then
	strRegPath = "コンピュータ\" & strParam
else
	strRegPath = "マイ コンピュータ\" & strParam
end if

' 既に regedit が実行中の場合はいったん終了させます
Set colProcessList = objWMIService.ExecQuery _ 
	("Select * from Win32_Process Where Name = 'regedit.exe'") 
For Each objProcess in colProcessList
	' 最後のウインドウの位置とサイズを保存する為の終わらせ方
	WshShell.AppActivate("レジストリ エディタ")
	Wscript.Sleep(500)
	WshShell.SendKeys ("%{F4}")
	Wscript.Sleep(500)
	' 上記終わらせ方が失敗した時の強制終了
	on error resume next
	objProcess.Terminate() 
	on error goto 0
Next 

WshShell.RegWrite "HKCU\" & strPath, strRegPath, "REG_SZ"

' レジストリエディタを起動します
Call WshShell.Run( "regedit.exe" )
' レジストリエディタが終わるまで待つ場合は以下のようにします
' Call WshShell.Run( "regedit.exe", , True )

REM **********************************************************
REM OS バージョンの取得
REM **********************************************************
Function GetOSVersion()

	Dim colTarget,str,aData,I,nTarget

	Set colTarget = objWMIService.ExecQuery( _
		 "select Version from Win32_OperatingSystem" _
	)
	For Each objRow in colTarget
		str = objRow.Version
	Next

	aData = Split( str, "." )
	For I = 0 to Ubound( aData )
		if I > 1 then
			Exit For
		end if
		if I > 0 then
			nTarget = nTarget & "."
		end if
		nTarget = nTarget & aData(I)
	Next

	GetOSVersion = CDbl( nTarget )

End Function





posted by lightbox at 2018-01-28 21:58 | VBScript | このブログの読者になる | 更新情報をチェックする

2018年01月26日


JavaScript でクリップボードに文字列をコピーする Clipboard.js の使用方法と注意事項

世の中の一般的な使用方法は、オリジナルサイトの概要と大差無いようですが、実際本当に使いたい環境を持っている人にとっては説明不十分です。

バージョン 1.5.4 までと 1.5.5 からでは仕様がすこし違う

問題は、element.focus(); ですが、これですと環境によってはコピー対象となるエレメントの位置までスクロールしてしまうので(実際このブログではしてしまった)ので、良く解らずに 1.5.4 以前を使用している場合は、バージョンアップしないほうがいいです。また、以下のソースコードからも解るように、focus() が実行されるのは、INPUT か TEXTAREA か その他の要素で contenteditable 属性を持っている場合だけなので、普通に DIV ならば focus() が実行される事はありません。
/*!
 * clipboard.js v1.5.12
 * https://zenorocha.github.io/clipboard.js
 *
 * Licensed MIT c Zeno Rocha
 */
    if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
        element.focus();
        element.setSelectionRange(0, element.value.length);

        selectedText = element.value;
    }
    else {
        if (element.hasAttribute('contenteditable')) {
            element.focus();
        }

        var selection = window.getSelection();
        var range = document.createRange();

        range.selectNodeContents(element);
        selection.removeAllRanges();
        selection.addRange(range);

        selectedText = selection.toString();
    }

    return selectedText;
この SyntaxHighlighter の右上のツールバーにある copy ボタンは、Clipboard.js を組み込んで実装しました。

実装

このような事をふまえて一般的な実装は以下のようになります
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.12/clipboard.min.js"></script>
<script>
$(function(){
	var clipboard = new Clipboard('.clipboard_element');
	clipboard.on('success', function(e) {
	    alert("クリップボードにコピーしました");
	});
	$(".action_btn").on("click", function(){
		var work = prompt("入力値をクリップボードにセット")
		$("#clipboard").text( work );
	})
});
</script>
<div class="clipboard_element" data-clipboard-target="#clipboard">
	<button type="button" class="action_btn">実行</button>
</div>

<div id="clipboard" style='position:absolute;left:-1000px;width:900px;white-space:pre-wrap;word-wrap:break-word;'></div>
new Clipboard で作成されるオブジェクトは、クリック対象の clipboard_element クラスを持つ要素を対象として作成されます。ここでは、clipboard_element は、DIV に対して設定されており、その DIV の中にアクションのトリガとなるボタンを配置しています。ボタンがクリックされると、まずそのイベントで必要なデータが画面外の要素に転送され、クリップボードにそのデータが送られます。要素間の関連性は、ボタンの親要素である DIV に data-clipboard-target="#clipboard" で設定されています
このソースコードには、いくつか重要な部分が存在します。 注意事項 1) ページにひとつだけ、クリップボード転送用の要素を DIV で作成する (body 要素直下でいいと思います) 2) DIV 内に改行やスペースを反映させる為に white-space:pre を設定する 3) ページ上から隠す為に、position:absolute;left:-1000px を設定する (クリップボートへコピーする為に選択する必要があるので、非表示では動作しません) 転送したテキストがこちら側へ表示しないように width:900px と word-wrap:break-word を指定する 4) クリックイベントは、ボタンである必要は無く、どのような要素でも良い 5) ボタンをクリックした時に必要な文字列を DIV に転送した後、DIV のクリックイベントが発生 実際の Clipboard.js のイベントは、ページ上のクリックイベントが全て終了してから発生するので、この順序である必要は無いのですが、仕様変更等あった場合にそなえてこの順序が良いと思います。 追記 ここで行っているような転送用のエリアを作成した処理を半自動でやるのがどうやら Advanced Options のあたりのようなのですが、ソース読むといろいろ scroll とかやってるので、環境によってはやはり問題がでるかもしれません。 Google、ChromeでのFlashブロックをさらに推進、12月にHTML5をデフォルトに 関連する記事 clipboard.js のコピーさせるテキストを自由にダイナミックに渡す方法は、Advanced Usage の text です。
posted by lightbox at 2018-01-26 18:57 | Comment(0) | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする

jQuery プラグイン : multiselect.js の使用方法とカスタマイズ

multiselect.js のダウンロードページ

( js と css と画像を同じフォルダに置いて、css 内の 画像の位置を変更して使います )
.ms-container{
  background: transparent url('./switch.png') no-repeat 50% 50%;
  width: 370px;
}


設置が簡単な multiselect.js ですが、( select 要素を選択するだけで標準的なリストを左右二つ作成してくれます )実際使うとなると、横幅や高さやパディングの調整は必要です。

さらに、デフォルトでは選択するリストが左側と決まっていますが、これは float で作成されているので、左右を入れ替えるだけで右側を選択できるようにできます
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://winofsql.jp/jquery/plugins/multiselect/jquery.multi-select.js"></script>
<link rel="stylesheet" href="http://winofsql.jp/jquery/plugins/multiselect/multi-select.css" type="text/css" />
<script type="text/javascript">
$(function(){
	$('#select_item').multiSelect({
		keepOrder: true,
		selectableHeader: "<div class='header_item'>商品候補</div>",
		selectionHeader: "<div class='header_item'>対象商品</div>",
		afterSelect: function(values){
			console.log( values[0] )
			console.log( $( "#select_item").children( "option[value='"+values+"']" ).text() )
		},
		afterDeselect: function(values){
			console.log( values[0] )
			console.log( $( "#select_item").children( "option[value='"+values+"']" ).text() )
		}
})
});
</script>
<style>
.header_item {
	padding: 5px;
	text-align: center;
	border: solid 1px #ccc;
	margin-bottom:2px;
	background-color: #eee;
}
.ms-container {
	width: 600px;
}
.ms-container .ms-selectable li.ms-elem-selectable, .ms-container .ms-selection li.ms-elem-selection {
	padding: 10px;;
}
.ms-container ul.ms-list{
  height: 300px;
}
/* 
	以下は、左右入れ替える為の CSS
	以下を設定しなければ、デフォルト仕様として左が選択可能になります   
*/
.ms-container .ms-selectable {
	float: right;
}
.ms-container .ms-selection {
	float: left;
}

</style>
<form
	method="get"
	id="target_form"
	target="my_ferame"
	action="http://winofsql.jp/php_get.php"
	accept-charset="utf-8">

	<input
		type="submit"
		name="send"
		id="send_check"
		value="送信">

	<select 
		multiple
		id="select_item"
		name="select_item[]">

		<option value='0001'>りんご</option>
		<option value='0002'>トマト</option>
		<option value='0003'>いくら</option>
		<option value='0004'>醤油</option>
		<option value='0005'>鳥唐揚</option>
		<option value='0006'>みりん</option>
		<option value='0007'>さんま</option>
		<option value='0008'>海苔</option>
		<option value='0009'>おにぎり</option>
		<option value='0010'>コロッケ</option>

	</select>
</form>
<br>
<iframe
	name="my_ferame"
	frameborder="1"
	scrolling="yes"
	width="600"
	height="200"></iframe>
キーも割り当てられていて、左右の矢印キーでリスト間移動ができ、上下矢印キーでリスト内を移動できます。
選択はスペースキーです。

イベント内(afterSelect と afterDeselect)では、values が引数となっていますが、上のソースでは、jQuery の セレクタで再度 SELECT 要素内の選択された OPTION のテキストも取得しています。
values は配列で定義されているので、values[0] として値を取得していますが、文字列と連結する場合はオリジナルサンプルでも直接使っていました
真ん中の矢印は画像なので、自作のものと置き換え可能です。 cssClass オプションの使い方 このオプションは、個別にクラスを実際定義するのでは無くコンテナにクラスを追加して個別にスタイル設定を可能にできるという意味があります。デフォルトでは、スタイルは全て ms-container というクラス名を先頭にしてセレクタが作成されているので、コンテナにクラスを追加すると、以下のような設定で cssClass に設定したクラス名を使用して個別に見栄えを変更できます。 このページでは、ms-container でクラス設定するように記述しているので、全ての multiSelect コンテンツが対象になりますが、デモ先では cssClass オプションを設定した multiSelect コンテンツ のみが設定されるようにしています。 cssClassselect_item を設定
<style>
.select_item {
	width: 600px;
}
.select_item .ms-selectable li.ms-elem-selectable, .select_item .ms-selection li.ms-elem-selection {
	padding: 10px;;
}
.select_item ul.ms-list{
  height: 300px;
}
/* 左右入れ替え */
.select_item .ms-selectable {
	float: right;
}
.select_item .ms-selection {
	float: left;
}
</style>

refresh メソッドの使い方

オリジナルページの説明には無い、refresh メソッドの意味なのですが、ソースコードを読んでみると最初に設定したオプションの状態でコンテンツを再構築していました。但し、SELECT 要素の現在の状態で再構築するので、見た目は変化ありません。

本来、最初に設定したオプションを変更してから実行すべきメソッドなのですが、オプション内容を変更する為のメソッドが用意されていません。ですが、内部で保持されているオプションの参照として、jQuery の data() メソッドで参照できる内容を使用できました。

これを使用すると、後から動的にスタイル設定やその他の設定を変更する事ができます。デモ先では、見栄えのスタイル設定を交互に変更しています( ソースもページ下部にあります )


	// ************************
	// CSS の切り替え
	// ************************
	$('#change_css').click(function(){
		var item1 = $("#select_item").data().multiselect.options.cssClass;
		if ( item1 == "target_item" ) {
			$("#select_item").data().multiselect.options.cssClass = "";	
			$("#select_item2").data().multiselect.options.cssClass = "target_item";
		}
		else {
			$("#select_item").data().multiselect.options.cssClass = "target_item";	
			$("#select_item2").data().multiselect.options.cssClass = "";
		}
		$('#select_item').multiSelect("refresh");
		$('#select_item2').multiSelect("refresh");
	});


ライセンスについて

WTFPL は、とても下品なライセンスですが、とても自由に使えるライセンスなのであまり気にしないでいいと思います。



posted by lightbox at 2018-01-26 15:32 | プラグイン:jQuery | このブログの読者になる | 更新情報をチェックする

Gmail に 実行可能なファイルの拡張子を持つファイルを格納した zip 書庫は送れません

2013-10-03 では、以下のようなメッセージと供に帰って来ました(現在は未確認)。
The original message was received at Thu, 3 Oct 2013 02:48:38 +0900
from [xxx.xxx.xxx.xxx]

  ----- The following addresses had permanent fatal errors -----

    (reason: 552-5.7.0 This message was blocked because its content presents a potential)

  ----- Transcript of session follows -----
... while talking to gmail-smtp-in.l.google.com.:
>>> DATA
<<< 552-5.7.0 This message was blocked because its content presents a potential
<<< 552-5.7.0 security issue. Please visit http://support.google.com/mail/bin/answe
<<< 552-5.7.0 r.py?answer=6590 to review our message content and attachment content
<<< 552 5.7.0 guidelines. h4si2001718pbd.143 - gsmtp
554 5.0.0 Service unavailable
結局、中に入っていた .vbs の拡張子を、.txt に変更して圧縮しなおして送信すると送れました。これについては、他でもそのようになるという記事をみかけました( .exe の入った書庫 )。 ▼ メッセージ内のリンクは以下のようになります。 Gmail でブロックされるファイルの種類 ※ 内容の要点
次の種類のファイルは送受信できません。(時々増えています)

.ade、.adp、.bat、.chm、.cmd、.com、.cpl、.exe、.hta、.ins、.isp、.jar、.js(新)、.jse、.lib、.lnk、.mde、.msc、.msi、.msp、.mst、.nsh、.pif、.scr、.sct、.shb、.sys、.vb、.vbe、.vbs、.vxd、.wsc、.wsf、.wsh
ウィルスや不正なソフトウェアからユーザーを保護するため、Gmail ではこのような特定の形式のファイルを添付できません。
圧縮形式には次のようなものがあります。

.zip、.tar、.tgz、.taz、.z、.gz、.rar
この内容読んでて、以下のような事実も確認しました
アーカイブが格納された、パスワードで保護されているアーカイブ
※ 悪質なマクロが埋め込まれているドキュメントもブロックされるそうです さらに、解決方法として Google ドライブの添付ファイルを送信する といいそうです。
ファイルが安全であるとの確信がある場合は、ファイルを Google ドライブにアップロードしてからドライブの添付ファイルとして送信するよう送信者に依頼してください。
最大 25 MB の添付ファイルを送信できます。複数のファイルを添付する場合は、合計 25 MB まで追加できます。 初回投稿 : 2013-10-03
posted by lightbox at 2018-01-26 13:13 | Google | このブログの読者になる | 更新情報をチェックする

Windows10 と Windows7 の Windows Update 画面を表示するコマンド

▼ Windows10 


ファイル名を指定して実行より
ms-settings:windowsupdate
( Windowsキ− + R で ファイル名を指定して実行 )

コマンドプロンプトから実行する場合
start ms-settings:windowsupdate

これは、ms-settings: URI スキーム による設定アプリの起動方法です。その他の URI スキーム一覧はこちら( Windows 設定アプリの起動 )にあります

Windows のショートカット一覧はこちらにあります

▼ Windows7


ファイル名を指定して実行より、『wuapp』
( Windowsキ− + R で ファイル名を指定して実行 )

▼ 共通
ファイル名を指定して実行より
control.exe /name Microsoft.WindowsUpdate

関連する記事

Windows7 の何かを開くコマンドライン

Windows7 の control.exe の引数




posted by lightbox at 2018-01-26 01:35 | Comment(0) | Windows | このブログの読者になる | 更新情報をチェックする

2018年01月23日


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

OneDrive へ移動

( TKMP.DLL 同梱 )

久しぶりにメールの処理の検証をしてみようと、最新(周辺)の 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_SendMail3
{
    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 メールを送受信する』というページにある、『POP3 または SMTP をサポートするアプリ』という中にあります

受信 (POP3) サーバー
サーバー アドレス: pop3.live.com
ポート: 995
SSL 暗号化: はい

送信 (SMTP) サーバー
サーバー アドレス: smtp.live.com
ポート: 25 (25 がブロックされている場合は 587)
認証: はい
TLS または SSL で暗号化された安全な接続: はい
ユーザー名: メール アドレス
パスワード: パスワード
一般的にどこのメールサービスでも、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)を使った、『さくらインターネット』用メール送信テンプレート




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

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



OneDrive よりダウンロード

テンプレートには、3.1.2 が入っていますが、Windwos10(64) + Visual Studio 2012 C# でテスト(2018-01-23)しました。デフォルトでは、32ビットでビルドされますが、『構成マネージャ』で 64ビットに変更しても動作しています。

さくらインターネット

現在スタンダードを運用していますが、月額 515円 容量 100GB です

メールメールアドレスを無制限で作成できます(当然容量内ですが)。
メールボックスの容量を1MBから2048MBまで任意に指定できます。
※ サーバのディスク容量がひっ迫していると、しきい値内であってもメールは届きません。
ウェブメール ※ 一応あります( そんなに力を入れてるとは思えないです ) ❸ メーリングリストは10個 コスト 月額515円 ( 年間一括支払いの場合、5,142円 ) レンタルサーバーとしては、さくらのブログの内容が Seesaa ブログの劣化版である事をのぞけば、結構いたれりつくせりだと思っています。 基本仕様一覧 Ruby は 1.8.x なんで、ちょっと古いと思っています。 データベース使用量は、こんなふうに昔から記述されています。
基本的に制限は設けておりませんが、共用データベースサーバでは使用量の目安がございます。
目安以上の容量を使用された場合、他のお客様への影響がでたり、障害が発生した場合、データの復旧が正常に行えない 可能性がございます。
SSL は 共有SSL が使えます。気軽にログイン部分等、暗号化可能です。 CRONの設定数は 5 です
MailClass mc = new MailClass()
{
    SmtpServer = "初期ドメイン",
    Port = 587,
    User = "ユーザ名@ドメイン",
    Pass = "パスワード",
    Protocol = AuthenticationProtocols.TLS
};

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

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);
		}

	}

}

関連する記事

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




posted by lightbox at 2018-01-23 21:23 | VS(C#) | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

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

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