ページ

2014年6月10日火曜日

2014年4月24日木曜日

Window server 2012 R2 で、Monacaデバッガー Window8アプリのデバッグ





MonacaデバッガーをWindows Server 2012 R2 にインストールして実行してみた。
起動するとログイン








Windows Server 2012 R2の開発者用ライセンスが必要とのメッセージが出て、取得しを試みたところ、以下のメッセージが出た。うーん残念。



それもそうかな。
MonacaのWindowsアプリはWindows8向けになっているので、Windows Server 2012 R2でMonacaデバッガーを実行させるには、それなりの準備が必要なようだ。

Windows Server 2012 R2でWindows8のアプリを動作させるには、「機能」を追加してあげる必要がると思われる。
これはWindows Server 2008でWindows7のアプリを動作させる時と同じ。

以下のサイトを参考しにして、機能を追加してみた。

Windows Server 2012でWindows 8で利用できる機能を追加する


Windows Server 2012 R2

















Visual Studio 2010 C#.NET で WordPress に自動投稿するプログラム


Visual Studio 2010 C#.NET で WordPress に自動投稿するプログラムを作るべく調査しまいた。


以下のサイトを参考にしました。
http://www.moonmile.net/blog/archives/1284


XML-RPCを使います。
参考サイトに従ってC#のプロジェクトをダウンロードしてコンパイルしました。

コンパイルを試した結果、.NET Framework 4ではうまくいきません。
.NET Framework 3.5で動作確認ができました。

現時点でのxml-rpc.netのバージョンは.2.5.0でした。


参考サイトのソースを少し変更して、コマンドプロンプトからすべて引数で動くように改修しました。


  • サンプルコード


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CookComputing.XmlRpc;

namespace WP_Post
{
    class Program
    {
        static void Main(string[] args)
        {
            Program pg = new Program();
            try
            {
                pg.url = args[0];   //<投稿先のURL/xmlrpc.php/>
                pg.username = args[1];  //ブログのユーザー名
                pg.password = args[2];  //ブログのパスワード
                string title = args[3]; //タイトル
                string content = args[4];   //記事内容
                pg.categoryID = int.Parse(args[5]);//カテゴリID
                // 投稿
                pg.BllogerNewPost(title, content);
            }
            catch (Exception ex)
            {
                Console.WriteLine("エラー:" + ex.Message);
                return;
            }
        }
        // ユーザー名
        string username = "<ブログのユーザー名>";
        // パスワード
        string password = "<ブログのパスワード>";
        // 投稿先のURL
        string url = "<投稿先のURL>";
        // 投稿カテゴリID
        int categoryID = 0;

        public void BllogerNewPost(string title, string content)
        {
            //プロキシクラスのインスタンスを作成
            IBlogger proxy =
                CookComputing.XmlRpc.XmlRpcProxyGen.Create<IBlogger>();
            //URLを指定
            proxy.Url = url;

            int id = 0;
            // content を生成
            content = string.Format("<title>{0}</title>", title)
                + string.Format("<category>{0}</category>", categoryID)
                + content;

            //blogger.getRecentPostsを呼び出す
            id = proxy.newPost(
                "",             // WordPressの場合は無視
                "1",            // 念のため1にしておく
                username,
                password,
                content,
                false);
            //結果を表示する
            Console.WriteLine("id: " + id);
        }
    }

    public interface IBlogger : IXmlRpcProxy
    {
        /// <summary>
        /// 新規投稿
        /// </summary>
        /// <param name="appkey">無視</param>
        /// <param name="blogid">無視</param>
        /// <param name="username">ユーザー名</param>
        /// <param name="password">パスワード</param>
        /// <param name="content">本文</param>
        /// <param name="publish">公開するかどうか</param>
        /// <returns>エントリのIDを返す</returns>
        [XmlRpcMethod("blogger.newPost")]
        int newPost(
            string appkey,
            string blogid,
            string username,
            string password,
            string content,
            bool publish);
    }
}





2014年4月8日火曜日

VBA エクセルマクロでCDOを使ったメール送信プログラム

BASP21を使ったメール送信プログラムは結構存在しますが、WinodwsにCDOが標準搭載されてからは、CDOを使っプログラムもリリースされるようになりました。
以下にサンプルプログラムを用意しました。
ヒントになればと思います。
GmailとYahoo mailで試したところ、本文のCRLFの扱いの違いがありました。
改行コードCRLFをLFに変換する機能は有った方が良いようです。
SMTPサーバーのプラットフォームの違いなのかもしれません。





サンプルプログラム

Option Explicit
'参照設定でCDOを参照しておくこと
Public passwd As String
Public sw As Byte

Sub MySendMail()
    Dim ret As String
    Dim szLogfile As String
    Dim szServer As String, szTo As String, szFrom As String
    Dim szSubject As String, szBody As String, szFile As String
    Dim flBody
    Dim i As Long
    Dim fs, a As Object
    Dim oMsg As New CDO.Message
    Dim szCC As String, szBCC As String
On Error GoTo Err_Handler
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set a = fs.CreateTextFile(Worksheets("設定").Cells(27, 1).Value, True) 'ログファイル
    passwd = ""
    oMsg.Configuration.Fields.Item(cdoSendUsingMethod) = cdoSendUsingPort '2
    oMsg.Configuration.Fields.Item(cdoSMTPServer) = Worksheets("設定").Cells(11, 1).Value 'SMTPサーバー名
    oMsg.Configuration.Fields.Item(cdoSMTPServerPort) = Worksheets("設定").Cells(13, 1).Value 'ポート番号
    oMsg.Configuration.Fields.Item(cdoSMTPConnectionTimeout) = 60   'タイムアウト値

    If Worksheets("設定").Cells(7, 1).Value <> "" Then  'CC
        oMsg.CC = Worksheets("設定").Cells(7, 1).Value
    End If
    If Worksheets("設定").Cells(9, 1).Value <> "" Then  'BCC
        oMsg.BCC = Worksheets("設定").Cells(9, 1).Value
    End If
 
    oMsg.Configuration.Fields.Item(cdoSMTPAuthenticate) = Worksheets("設定").Cells(15, 1).Value 'SMTP認証
 
     '要パスワード認証の場合
    If Worksheets("設定").Cells(17, 1) = 1 Then
        UserForm1.Show
        If sw = 1 Then
           oMsg.Configuration.Fields.Item(cdoSendPassword) = passwd
         Else
            MsgBox "送信処理をキャンセルしました。"
            GoTo Exit_sub
         End If
    End If
 
    If Worksheets("設定").Cells(21, 1) = 1 Then
        oMsg.Configuration.Fields.Item(cdoSMTPUseSSL) = True    'SSL暗号化
    Else
        oMsg.Configuration.Fields.Item(cdoSMTPUseSSL) = False    'SSL暗号化しない
    End If
 
    oMsg.Configuration.Fields.Item(cdoLanguageCode) = Worksheets("設定").Cells(23, 1).Value '文字コード
    oMsg.Configuration.Fields.Update

 
    ' メール送信結果を記録するファイル名を指定します。
    szServer = Worksheets("設定").Cells(11, 1) ' SMTPサーバ名
    '
    With Worksheets("宛名及び置換文字")
        If .Cells(1, 3) & .Cells(1, 7) = "" Then
            MsgBox "タイトルとFROMを入力してください"
            GoTo Exit_sub
        Else
            If MsgBox("タイトル:" & .Cells(1, 3) & vbCrLf & "送信元:" & .Cells(1, 7) & vbCrLf & vbCrLf & "上記でよろしいですか?", _
                vbOKCancel, "確認") = vbCancel Then
                GoTo Exit_sub
            End If
        End If
        szSubject = .Cells(1, 3)    ' 件名
        szFrom = .Cells(1, 7)   ' 送信元
     
        If .Cells(1, 10) = "高" Then
            oMsg.Fields("urn:schemas:mailheader:Importance") = "High"
            oMsg.Fields("urn:schemas:mailheader:Priority") = 1
            oMsg.Fields("urn:schemas:mailheader:X-Priority") = 1
            oMsg.Fields("urn:schemas:mailheader:X-MsMail-Priority") = "High"
            oMsg.Fields.Update
        End If
        If Worksheets("設定").Cells(19, 1).Value = "" Then
            oMsg.Configuration.Fields.Item(cdoSendUserName) = Cells(1, 7).Value 'メールアドレス
        Else
            oMsg.Configuration.Fields.Item(cdoSendUserName) = Worksheets("設定").Cells(19, 1).Value   'ログインID
        End If
        oMsg.Configuration.Fields.Update
     
        oMsg.From = szFrom
        oMsg.Subject = szSubject
     
     
        i = 3
        Do While .Cells(i, 1) <> "END"
            If .Cells(i, 1) = "○" Then
                szTo = .Cells(i, 5)    ' 宛先
                szBody = .Cells(i, 6) ' 本文
                If Worksheets("設定").Cells(25, 1).Value = 1 Then '改行コードCRLF
                    szBody = Replace(szBody, vbLf, vbCrLf)
                End If
                szFile = .Cells(i, 11) '添付ファイル
                oMsg.To = szTo
                oMsg.TextBody = szBody
                If szFile <> "" Then
                oMsg.AddAttachment szFile
                End If

                On Error GoTo ErrHandler1
                 oMsg.Send
                  .Cells(i, 1) = "完了"
cont1:
            End If
            i = i + 1
        Loop
    End With
    ' パラメータエラーのときは、戻り値にエラーメッセージが返ります。
    MsgBox "終了しました"
    GoTo Exit_sub

ErrHandler1:
    MsgBox "エラー:" & Err.Number & vbCrLf & Err.Description
    a.WriteLine (Date & " " & Time & " " & Err.Number & "-" & szTo & "-" & Err.Description)
    Worksheets("宛名及び置換文字").Cells(i, 1) = "エラー"
    Resume cont1

Err_Handler:
    MsgBox Err.Description, vbCritical, "Error"
    GoTo Exit_sub

Exit_sub:

   a.Close

End Sub

2014年4月7日月曜日

今更ながら磁気カードについて考える

今はRFID・ICカードが普及して、今更磁気カードなんて使わないでしょ!?
そう思われる。

磁気カードはスキミングにより、サクサク読み取れます。
カードのコピーは多少の技術的知識があれば、お茶の子さいさい、への河童。なわけです。

セキュリティーの面からもICカードを利用するのが望ましい事は誰でも納得出来るところです。

しかし、磁気カードはまだまだ使われている。


理由は、「カードの単価が安い」という事に尽きる。
無料でカードを顧客に配布する様なカードソリューションにとっては、重要な要件になる。

ICカードはMifare Ultra rightはもっとも安いICカードだが、それでも磁気カードの方が安い。

したがって、磁気カードは市場から無くならない。

VB.NETからExcel2007のソート機能を使う

VB.NETからExcel2007のソート機能を使う


ソートキーが文字列の場合、順番を指定してソートしてあげないと、希望通りのソートができないですよね。
VB.NETから簡単にエクセルのソート順を文字列していして実行する方法を見つけたので書いておきます。
VBレスキュー(花ちゃん)のサンプル投稿用掲示板
を参考にしてみたものの、いまひとつピンとこない。

半日悩んだ結果、こんなに簡単なコードで、出来る事がわかりました。
「CustomOrder」を使います。


以下にサンプルコードを書いておきます。
既にエクセルオブジェクトが読み込まれていて、アクティブシートが選択されている状態であることを前提にしています。
「strソート文字列」はソートする文字列群がすでに代入された、StringのArrayListとします。

「CustomOrder」はシート毎に設定すると考えられます。
シートを選択してSort.SortFieldsに設定してあげたらできました。


2013年8月5日月曜日

FDT.exeがインストールされているか自動判定する


PCと接続されている機器のファームウェアのバージョンアップを自動化したいという要求は多々あると


Renesas FDT.exe

レジストリのUninstallリストを見る方法

レジストリのUninstallプログラムリストを見れば、既にインストールされているプログラムの一覧を取得できる。
以下がそのレジストリ名。

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{プロダクトID}

FDTのプロダクトIDを調査した。

  • V409 {376379F3-E708-453E-B5C1-FB60675C513C}
  • V408 {0776792E-F51C-4CE5-A4FB-86E126DB9C81}
  • V403 {29170013-CC82-4D81-BEB3-970662DD7A98}
  • V401 {287BC16B-9185-4E2B-B713-557A1ADF9590}
手元にあるいくつかのバージョンを
ということで、各バージョンのプロダクトIDが異なるため、全てのバージョンをのプロダクトIDを事前に調べて、全部を検知するのは、賢いやり方では無さそう。


関連付けファイルの情報などのレジストリを見る方法

そこで、別の方法を考えてみる。
FDTのインストール時にデフォルトでは拡張子に関連付け処理が適応される。
ということは、関連ファイルが起動される際の、起動プログラム情報がレジストリに追加されているはずである。
レジストリを調査していると、以下のレジストリ名を発見した。

  • HKEY_CLASSES_ROOT\FDT4.Config\shell\open\command

この中を見ると

  • "C:\Program Files\Renesas\FDT4.09\fdt.exe" "/DISCRETESTARTUP" "w4fRun \"%1\""

と書いてあった。バージョンによってフォルダ名が違うものの、インストールされた痕跡はこれで分かる。痕跡と書いたが、アンインストールされてもこの情報は残っている為、実態があるかどうかは別途調べなければならない。

レジストリの値を抽出する方法

バッチファイルでレジストリの値を抽出すること自体はとても簡単。

【レジストリの値を抽出する】

SET FDT_REG_KEY_CONF=HKEY_CLASSES_ROOT\FDT4.Config\shell\open\command
FOR /F "TOKENS=2,3,* delims= " %%I IN ('REG QUERY "%FDT_REG_KEY_CONF%"') DO (
IF "%%I"=="REG_SZ" SET FDT_EXE_CMD_VALUE=%%J
)


ここまでは簡単。
しかし環境変数FDT_EXE_CMD_VALUEに入る文字列は

  • C:\Program Files\Renesas\FDT4.09\fdt.exe"

となっている。最後のダブルクォーテーションが余分だ。

文字列からダブルクォーテーションを削除する方法

色々試してみたが、テキストのテンポラリファイルに一旦掃き出すがのもっとも簡単だと思われる。

ECHO %FDT_EXE_CMD_VALUE%>tmp.txt
などで、テキストに掃き出してから以下のバッチファイルを呼び出す。

【ダブルクォーテーションを削除する.bat】

REM BATファイルのパラメータ
REM %1 対象テキストファイル名
if "%1"=="" goto end
set fname=%~1
copy %fname% org >nul
type nul >%fname%
for /f "delims=" %%a in ( org ) do (set line=%%a&& call :sub)

del /f org
goto end

:sub
set l=%line:"=%
>>%fname% echo %l%
goto :EOF

:end





バッチファイルで文字列からダブルクォーテーションを削除する。


バッチファイルで文字列からダブルクォーテーションを削除する。

バッチファイル制御を試みると、この問題にぶち当たることがあります。
例えばレジストリの内容を見て、プログラムフォルダを検索するなど、PATH名に空白がある場合は文字列がダブルクォーテーションで囲まれている。
そこにプログラムパラメーター等の文字列がさらに書き込まれている場合、for文で区切り文字処理がうまくできず、片方だけダブルクォーテーションが残ってしまってガックリ来たりします。
そうなると意外に面倒くさい。
ダブルクォーテーションが残ってしまった文字列をテキストファイルに吐き出して、そのテキストファイルから、ダブルクォーテーションを削除するバッチファイルを作成してみた。



2013年7月31日水曜日

Google API を使って自動的に記事を投稿する サンプルサイト

Google API を使って自動的に記事を投稿する サンプルサイト

今月は、Google API を使ってBloggerに投稿するプログラムについて勉強しました。
集大成として、サンプルサイトを作成しました。

http://p-mans.blogspot.jp/


サイト構築の要領

  • 専用のBloggerアカウントを用意
  • Azure仮想デスクトップを用意
  • 特定のサイトから過去記事を検索するロボットを作成
  • このロボットを複数用意して、タイムスケジューラーで定期的に起動
  • タイムスケジューラーはAzureの環境に用意
  • ロボットは記事の日付、タイトルを認識、不要なタグの削除などを行い、特定のbloggerへ自動投稿する

問題点

bloggerへの自動投稿には以下の問題点があります。
  • 1日に投稿出来る件数の制限
  • 利用できるタグの制限

総評

問題点が見えれば、回避方法が見つかりますので、なんとか構築に成功しました。
この構築に掛かった工数は試行錯誤もあるので、約10人日でした。
今回は仕事に関係するパチンコ業界の記事を中心にしたサイトを作ってみました。



2013年7月29日月曜日

Google API で Bloggerに投稿する際に、ラベル、スケジュール日付を付加する。

Google API で Bloggerに投稿する際に、ラベル、スケジュール日付を付加する。
Google.GData.Clientを参照する。
using Google.GData.Client;
以下がサンプルコード。

schemeに"http://www.blogger.com/atom/ns#" を指定するのが重要なポイントになります。

static AtomEntry PostNewEntry(Service service, Uri blogPostUri
 , string Title, string HtmlContent, DateTime Update
 , string Name, string Email)
{
    Console.WriteLine("\nPublishing a blog post");
    AtomEntry createdEntry = null;
    if (blogPostUri != null)
    {
        // construct the new entry
        AtomEntry newPost = new AtomEntry();
        newPost.Title.Text = Title; //タイトルはダブってもエラーにならない
        newPost.Published = Update;   //日付
        newPost.Content = new AtomContent();
        newPost.Content.Content = HtmlContent;
        newPost.Content.Type = "xhtml";
        newPost.Authors.Add(new AtomPerson());
        newPost.Authors[0].Name = Name;
        newPost.Authors[0].Email = Email;
        newPost.Categories.Add(new AtomCategory(
            "Label1"   //term
            , "http://www.blogger.com/atom/ns#" //scheme
            ));
        try
        {
            createdEntry = service.Insert(blogPostUri, newPost);
            if (createdEntry != null)
            {
                Console.WriteLine("New blog post created);
            }
        }
        catch
        {
        }
    }
    return createdEntry;
}


Service.Insert()でエラーが発生する場合は、HTMLのタグに不整合がないか確認してみよう。

Service.Insertのエラーについて

Service.Insertで発生するエラーについてはいくつか考えられる。

  1. HTMLのタグに不整合
  2. 投稿件数オーバー・セキュリティーロック

HTMLのタグに不整合

いつか使えないタグ、というか古い仕様は受け付けない。
例えば<br>は×、</ br>出ないとだめ。
その他にも対応しないタグが有るようです。

投稿件数オーバー・セキュリティーロック

1日の投稿件数が、ある一定数(?)を超えると、セキュリティーロックが掛かる。
ハッカーが他人のブログをのっとって、ロボットが書き込んでいると判断されるようだ。
手動での各込は出来るが、投稿時にセキュリティ画像に表示される文字の入力が必要になる。
APIではそれが困難である為、エラーが発生する。
セキュリティーロックは翌日になると、解除されるようだが、セキュリティーロックが掛かった日はAPI投稿は中断し、一日に投稿する数を調整する必要がある。
ある一定数(?)というのが分からないが、100投稿もすればセキュリティーロックが掛かるのも当然だと言える。

2013年7月23日火曜日

Visual Studio 2010 多言語対応時、デザイナーでエラーが発生する!

Visual Studio 2010 で作成したWindow Form アプリケーションを、中国語対応することになったので、いろいろとやり方を調べた。

既存ソースで試すのは不安だったので、新規アプリケーションを作成し、FormのLocalizableプロパティを「True」に設定し、Languageプロパティを「中国語」に設定してみた。

あれ?
Form.zh.resxができると思いきや、できないではないか。

で、わかったことは、この時点では自動作成されない。
Form上のコントロールのTextを変更するなど、デフォルトの設定との違いが発生した時点で、自動作成される。
また、違いのある箇所だけ、Form.zh.resxにリソースが追加される。

フー。
無事作成された。

参考サイト:Windowsフォームを多言語対応にするには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/314winmultilang/winmultilang.html


Form上のコントロールはこれでよいか、MessageBoxのメッセージ文字列は直接コード上にあるので、どうすぺきかを調べた。

どう考えてもメッセージ文字列をResourceファイルにしておく必要がありそう。

参考サイト:
C#でのアプリケーション設定の取得・保存方法
http://d.hatena.ne.jp/seraphy/20120708

多言語対応アプリ作成
http://hshimaji.web.fc2.com/mui/project.html


で、上記2点の作業を本番のアプリケーションソースに修正を加える。


順調に作業を進めていたが、ところがどっこい。
デザイナでエラーが発生した。


少々パニック。
ソースを元に戻しても、発生する。


よくよく調べると、Form.Designer.csの中で、Form上のコントロールのプロパティ[ImageKey]に、メッセージ文字列をリソース化した際の文字列の名称を代入しようとして、エラーになっている。

ご丁寧に、すべてのLabelとButtonの[ImageKey]プロパティーに代入しようとしてくれる。

この仕様は不具合なのか良くわからない。

とにかく、このままではコンパイルもできないので、Form.Designer.csの中の[ImageKey]プロパティーに、不要な代入をしようとする記述を削除する。

何とかデザイナー編集が表示されるようになった。


しかし、またデザイナー編集で、コントロール上のテキストを変更すると発生する。
なんだこれは!



2013年7月22日月曜日

ヤンゴン向けコンテナ輸送について

ヤンゴン向けのシッピングサービスを行っている会社を調べてみる。



ジー・ティー・シー エイシア
http://www.gtc-asia.co.jp/

中古車輸出が盛んになって来ているので、その手の情報も提供してくれている。




日本郵船
http://www.nyk.com/

やるやると言っているが、サービスはスタートしたのだろうか。
シンガポールからの振替だとか。


2013年7月20日土曜日

CString をprintf で使ってハマッた

例えば次のような単純なコードのようにCString をprintf()を使って出力しようとする。

CString buf = "abcd";
printf_s("%s\n", buf);


で、出力結果が
a
となってしまって、1文字しか出ない。


この問題、色々なサイトに記事があるが、「printfはCStringにAFXが対応しているぜ。」と書いてあって、なかなか解決方法が見つからなかったが、答えは簡単だった。

printf_s("%S\n", buf);

のように%sを%Sの大文字にしてあげると出た!

あー、1日はまってしまった。
でもこれで「スッキリ」。

2013年7月18日木曜日

最近の扇風機について考える

最近、電器量販店に行くと、新型の扇風機が並んでいる。

ダイソンの羽の無い扇風機のデビューは衝撃的だった。

その影響もあるが、やはり震災の影響で、電力の消費に関心が増えた事によるところは大きいと思う。

ミストが出る扇風機なんかも出てきてる。
なんかすごい進化している気がするね。


これからは、エアコンより扇風機か?

エアコンの原理はフロンガスの気化熱により、冷えるわけですが、このミストも水分が扇風機の前で蒸発するので、よりひんやりと涼しい風が得られるって訳です。

なるほど、良く考えたものだ。


そこでアイデア。

  • レース布のようなものを常時湿らせて、扇風機の風の吸入側に装着して、水分の蒸発を促して涼しい風を得る。
  • 水分の補給はペットボトルでOK。
  • あらゆる扇風機に装着可能。

で、風の温度が0.5度下がります!とか、体感温度で1度下がります!とかで、1000円ぐらいの簡単なものがあれば、そこそこ売れないかな?
特に東南アジアで売れないだろうか。