着いた! 早!

朝会社に行くと、机に箱が置いてあって、何かな? と開けてみると・・・先日注文したIllustorator CS5でした。。。Illustrator CS5、28日発売だったはずなのだが・・・?う~ん・・・。お金下ろしてこないと・・・。

いつも思うんだけど、パッケージソフトウェアの外箱って必要ないんじゃないかなぁ~・・・。薄型のCD・DVDケースとかでも十分だと思うんだけど・・・。

Illustrator CS5のパッケージ

アップグレード版のインストーラーって、なんで前のバージョンを削除してくんないでしょうねぇ・・・?CS5をインストールした後、CS2をアンインストールしたらCS5の関連付けが解除されて・・・またCS5をインストールし直し。なんとかならんの・・・?

というわけで、

Illustrator CS5


Win7+CS2より、かなり使いやすくなりました(^^;
 

Adobeといえば・・・

Appleと仲が良い会社というイメージが未だにあるんだけど、ちょっと前のアドビ vs アップル のFlashに関する応酬はで、実はそうじゃないんだな、と思いました。コカコーラvsペプシみたいな日本では到底起こりえない、アメリカの典型的な企業間闘争でしょうか(笑) これに、Googleが絡んできているので、もうメチャクチャ。な感じです。

最近、やたらとHTML5というキーワードが情報系のニュース記事で頻繁に見かけるようになってきました。HTMLは、HTML4以降主に二つの系列に分かれてきています。
一つは、XHTML。XHTMLは、HTMLをXMLのサブセットとするような感じです。もう一つは、このHTML5です。HTML5はよりWebアプリのため、と言ってもいいようなぐらいですが、まだ標準化作業のまっただ中です。

なぜこれほどまでに、HTML5が重要なんだろうか? と考えたとき、行き着く先は「金になる」からなんだと思います。

iPhoneアプリにしろ、アンドロイドアプリにしろ、ほとんどのアプリは、ネット環境前提のWebアプリで、その実態はHTML文とJavascriptのようなスクリプトで駆動するタイプかなと思います。

パソコンにインストールしてあるブラウザでウェブサイトを見る、というスタイルは、この先主流ではなくなる、これは間違いないでしょう。ウェブサイトを見るためだけにパソコンを立ち上げるなんて、ナンセンスですよ、今の時代。僕自身、家の無線LAN経由でiPod Touchを使って見ることの方が圧倒的に多いです。iPadを代表とする、5~10インチ端末の出現で、この流れは加速するはずです。

携帯端末に自由にHTMLとJavascriptを転送できて、それらをその携帯端末で見ることが出来れば便利なのにな・・・と常々思ってました。そこんところを制限して金儲けにしているのが、現在のアプリストア。そのアプリは、端末に搭載されているブラウザで駆動するHTML5とスクリプト。

つまり、極端なこというと、HTML5とJavascriptで組んだ、単なる写真のスライドショーであっても、もし売れればお金になる、ということ。売れるか売れないかは別にして、もっと極端なことを言うと「文字を表示するだけ」のHTMLファイルでもWebアプリだ!と言い張っても通るわけ。

以前ならHTMLとスクリプトでは1円にもならなかったものが、携帯端末から自由を奪う(制限をかける)ことで、コンテンツの保護と金儲けを実現させた、このモデルを考え出して実現した人たちって、頭がいいんでしょうねぇ。
(学歴とか偏差値とかいう意味じゃないですよ、もちろんビジネス的な頭の良さ。)

まぁ、商売人にとってHTML5は「金儲け」のツールでしかないんでしょうねぇ。

コンソール(CMD.EXE)のログを取る (不完全版)

コマンドプロンプト(CMD.EXE)の操作や出力ログを全部取りたい、と思っては見たものの、Windows標準の機能だけでは完全なログを取ることができません。リダイレクトしても入力したログが記録されないし、何より、コンソール画面に出力されないので入力しつつ、出力も表示しながら、かつすべてのログをとる、ということが標準でできません。

確かUnix系のOSなら、teeコマンドというものでできるらしいのですが・・・Windowsにはありません。そういう需要がWindowsには少ないのか、ネットで探すと、VBSスクリプトで実装しているもの(Tee.vbs)もありますが・・・。

これが Cygwin であれば、TeratermやPedorosaのようなターミナルエミュレータでCygwinに接続することですべてのログを取ることが可能ですが、残念ながらこれらのターミナルからCMD.EXEには接続できません。

というわけで、C++で強引に作ってみよう、というわけで、とりあえず動作チェック・テスト用コードを書いてみました。

仕組み自体は、CreateProcessで標準入出力をリダイレクトしたCMD.EXEのプロセスを作って、匿名パイプで出力を取得してファイルと画面に出力する、という至って普通のやり方です。

なんとか強引にコーディングして、標準出力と標準エラー出力はファイルに落とすことはできましたが、まだ入力のログがとれてません。また来週にでも完全版を書きたいと思ってます。。。

/****************************************************************

  ■CMD.EXE のログをとる不完全版テストコード
     (入力がログに落ちません)

****************************************************************/

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define CLOSEHANDLE(X) {if(X)CloseHandle(X);}
#define SAFEDELETE(X) {if(X)delete (X);}
#define BUFFER_SIZE 1024
#define SPIN_COUNT 4000
#define LOGFILE_PATH TEXT("cmdlog.log")

//匿名パイプをラップしたもの
struct PipeHandle
{
  HANDLE hRead;
  HANDLE hWrite;
  SECURITY_ATTRIBUTES sa;

  PipeHandle() : hRead(NULL),hWrite(NULL)
    {
      sa.nLength = sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      sa.bInheritHandle = TRUE;

      ::CreatePipe(&hRead,&hWrite,&sa,0);
    }
  ~PipeHandle()
    {
      CLOSEHANDLE(hWrite);
      CLOSEHANDLE(hRead);
    }
};

//スレッド関数に各種変数を渡すために使用するコンテキスト
struct Context
{
  PipeHandle *lpStdHandle;
  HANDLE hFile;
  HANDLE hStdio;
  LPCRITICAL_SECTION lpCriticalSection;
  PBOOL pThreadMustTerminate;

  Context(LPCRITICAL_SECTION lpcs,PBOOL ptht) 
    : lpCriticalSection(lpcs),pThreadMustTerminate(ptht)
    {}
};

//パイプから出力を読み取るスレッド関数
DWORD WINAPI ReadOutputProc(LPVOID lpParameter)
{
  Context *context = (Context*)lpParameter;

  TCHAR pBuffer[BUFFER_SIZE] = {0};
  DWORD dwRead = 0,dwWrite = 0;

  while(!(*context->pThreadMustTerminate))
    {
      BOOL b = FALSE;
      DWORD dwReadAvail = 0;
      do
        {
          b = ReadFile(context->lpStdHandle->hRead,(PVOID)pBuffer,BUFFER_SIZE,&dwRead,NULL);
          if(dwRead > 0)
            {
              EnterCriticalSection(context->lpCriticalSection);
              WriteFile(context->hFile,(PVOID)pBuffer,dwRead,&dwWrite,NULL);
              WriteFile(context->hStdio,(PVOID)pBuffer,dwRead,&dwWrite,NULL);
              LeaveCriticalSection(context->lpCriticalSection);
            }
          if(*context->pThreadMustTerminate == TRUE)
            break;
        }
      while(b == TRUE && dwRead > 0);
    }

  return 0;
}

//スタートアップ
int _tmain(int argc,_TCHAR **argv)
{
  //CMD.EXEのパスを格納するバッファ
  TCHAR szCmdPath[MAX_PATH+1] = {0};
  
  //ログを書き込むファイル
  HANDLE hFile = NULL;
  
  //CreateProcessに必要な構造体
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  //パイプ
  PipeHandle *ppStdOut = new PipeHandle();
  PipeHandle *ppStdErr = new PipeHandle();

  //スレッドの同期処理に必要
  CRITICAL_SECTION cs;
  BOOL bThreadMustTerminate = FALSE;

  //標準入力コンソールハンドル
  HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  
  //スレッドに渡すコンテキスト
  Context ctxOut(&cs,&bThreadMustTerminate);
  Context ctxErr(&cs,&bThreadMustTerminate);

  //クリティカルセクションオブジェクト初期化
  InitializeCriticalSectionAndSpinCount(&cs,SPIN_COUNT);

  //CMD.EXEのパスを環境(システム)変数から得る。
  if(0 == GetEnvironmentVariable(TEXT("COMSPEC"),szCmdPath,MAX_PATH+1))
    {
      _tprintf(TEXT("環境変数 COMSPEC 取得失敗\n"));
      return 0;
    }

  //ログファイルをオープン
  if((hFile = CreateFile(LOGFILE_PATH,
                         GENERIC_WRITE,
                         0,
                         NULL,
                         CREATE_ALWAYS,
                         FILE_ATTRIBUTE_NORMAL,
                         NULL)) == INVALID_HANDLE_VALUE)
    {
      _tprintf(TEXT("CreateFile が失敗しました"));
      goto cleanup;
    }
  

  // CMD.EXEのプロセスを生成
  ZeroMemory((LPVOID)&si,sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  si.dwFlags    = STARTF_USESTDHANDLES;
  si.hStdInput  = hStdInput;
  si.hStdOutput = ppStdOut->hWrite; //パイプにリダイレクト
  si.hStdError  = ppStdErr->hWrite; //パイプにリダイレクト

  if(FALSE == CreateProcess(NULL,
                            szCmdPath,
                            NULL,
                            NULL,
                            TRUE,
                            NORMAL_PRIORITY_CLASS,
                            NULL,
                            NULL,
                            &si,
                            &pi))
    {	
      _tprintf(TEXT("CreateProcess 失敗 : %d"),GetLastError());
      goto cleanup;
    }
  
  //スレッドに渡すコンテキストのメンバをセット
  ctxOut.lpStdHandle = ppStdOut;
  ctxOut.hFile = hFile;
  ctxOut.hStdio = GetStdHandle(STD_OUTPUT_HANDLE);
  
  ctxErr.lpStdHandle = ppStdErr;
  ctxErr.hFile = hFile;
  ctxErr.hStdio = GetStdHandle(STD_ERROR_HANDLE);

  /* スレッド作成 */
  HANDLE hThread1 = CreateThread(NULL,0,ReadOutputProc,&ctxOut,0,NULL);
  HANDLE hThread2 = CreateThread(NULL,0,ReadOutputProc,&ctxErr,0,NULL);

  //CMDプロセス終了まで待機
  WaitForSingleObject(pi.hProcess,INFINITE);
  
  //スレッド終了通知
  bThreadMustTerminate = TRUE;

  //パイプの削除
  SAFEDELETE(ppStdOut);
  SAFEDELETE(ppStdErr);
  
  //クリティカルセクションオブジェクトを削除
  DeleteCriticalSection(&cs);

cleanup:
  //ハンドルを閉じる
  CLOSEHANDLE(hFile);
  CLOSEHANDLE(pi.hThread);
  CLOSEHANDLE(pi.hProcess);
  CLOSEHANDLE(hThread1);
  CLOSEHANDLE(hThread2);

  return 0;
}

なんか・・・汚いコードだな、相変わらず・・・。
これだけなら、

CMD.EXE 2>&1 |  xxxxxx

と変わらないなぁ・・・。


コマンドプロンプトのログを取る(完結)
コマンドプロンプトのログを取る(その3)
コマンドプロンプトのログを取る (その2)

雨ですねぇ

GW中に出かけたきり、週末はほとんど部屋にヒキコモリです。
仕事で使うスクリプトやら個人的に使うプログラムやら、会社で仕事中にできなかったコーディングをシコシコ夜遅くまで書いて、気づいたら午前3時過ぎとか・・・。

PC用のスピーカー、右から音が出なくなってしまいました。友人からもらったもので、もうかれこれ十年ぐらい使っているのですが、そろそろ買い替えたいなぁ~、と思ってた矢先だったんで、家電量販店に買いに、今日行ってきました。外は暴風雨です(笑)

で・・・とりあえず値段は高くても良いものを買っておこう・・・と思い見て回ってましたら・・・

BOSE M2

に行き着きました(^^;;; 小さくて音も良さそうです。
しかし・・・値段が・・・約4万・・・・。うーーーーーーん・・・・。
IllustratorCS5のアップグレード版を会社で注文しちゃったしなぁ・・・とりあえず・・・ネットでよく調べてから、と思い、衝動買いは阻止(^^;;;

さて・・・どうしましょうか・・・。

このままだと音楽聴けないので、音が鳴らないスピーカーを分解すると、接点が錆び付いて断線しかかっていた模様。ハンダごてとかないので、適当に線を巻き付けてテープで固定・・・。取り敢えず復旧。

今は・・・M2を、買うべきか、今のままで我慢するか・・・悩んでます。
悩んでる内容が小さいですな~(ーー;;; つくづく小さい人間ですな・・・・。

VPSサーバー初期化

週末から、SSHクライアントでログインできない状態が続いていましたが、やっと今日初期化してもらい、復帰しました。原因は分かったので、早速対策。

対策といっても・・・rootログインを可能にしただけなんですけど・・・(ーー;;; なんかあってもROOTログインできれば、なんとかなるでしょ(笑)設定が終わり次第rootログイン不可に戻すつもり・・・。
パスワード認証を不可にしているので、まぁ、秘密鍵を漏らさないようにすれば大丈夫でしょう。

初回は試行錯誤的に設定をしていたので時間がかかりましたが、設定内容はその都度記録しているので、今回はラクチンです。

VPSサーバーの初期化は、DTIのサポートに連絡してDTI側で初期化を行う、という形に今はなっているみたいですけど、ユーザー側で初期化を行うことができるように今後はなる予定みたい。

既にアナウンスされている”Cloud Shell for Windows”もどういうものなのか詳細が分かりませんが、楽しみです。
 

それとは別に・・・いつまでもIPアドレスでアクセスするのは非常に不格好なので早くドメイン名を取得したいのですが・・・。良いドメイン名が思いつかない・・・。めぼしい名前は既に全部取られているし、う~ん・・・どうしたものか・・・。

sshでログインできない

先日交付された身体障害者手帳、高速道路も半額になるみたいで、早速手続きしに行ってきました。ETCセットアップ証明書、車検証、免許証、ETCカードなどなど必要なものを持って区役所へ~。ETCで自動的に割引処理されるまで2週間ほどかかるみたいす。といっても、高速道路は月一回の通院ぐらいであまり乗らないので、あまりメリットがないかも・・・。
 
 
DTI の格安VPSサーバー、ときどき重くてフリーズするけど(たぶん他ユーザーが重い処理させてるんだと思うのですが)、安いので文句言いっこなしです(^^;;;

で、いろいろ設定を見直したり、古いバージョンのプログラムを更新したり・・・とやってて、さて本格的に運用するか!と思って一度 再起動かけたんですが・・・↓のメッセージが出て、SSHクライアントで操作できなくなってしまいました。

Server refused to allocate pty

ログイン認証は出来ているんだけど、仮想端末が割り当てられてないのでシェルアクセスできない(ーー;;; WinSCPでなんとかコマンドを送ることはできるんだけど、suなど入力が必要なコマンドが実行ができないので、ROOT権限が得られない。設定を変更できない。

にっちもさっちもいかず、技術サポートにメールを出す・・・出したんだけど・・・/etc/ssh/sshd_configの初期化を提案されました。。。ん? いや、そうじゃなくて・・・(^^^;;; と思いつつ、それで治るんなら・・・とsshd_configの初期化を依頼しました。・・・・が、当然ですけど・・・そんなことで直るわけぢぁなく・・・。

しょうがいないので、VPSサーバーの初期化(元に戻す)が可能かどうかメールで問い合わせ中。。。

このエラーメッセージをググってみると割とメジャーなものらしく、簡単に解決方法が得られます。が、そもそもシェルアクセスでルート権限になれないので、途方に暮れてます・・・。

やっぱり、安いPCで自宅サーバーを起てた方がいいかもしれない。。。ん~・・・・。