わんくま同盟わんくま同盟
わんくま同盟 -> Blog's
わんくま同盟メンバの最新の記事
http://mainichi.jp/life/edu/news/20120125k0000e040231000c.html
二宮金次郎像:勤勉精神いまは昔、各地で撤去相次ぐ - 毎日jp(毎日新聞)
子供が働く姿がいけないとか、歩きながら本を読むのは危険とか
金次郎
は実は悪者の象徴だったんですね!
>尊徳記念館の小林輝夫解説員(76)は「金次郎は賢人の名言集から学び、自分にできることに全力を尽くした。少子高齢化で厳しい社会を背負うことになる今の子どもたちこそ、彼の姿勢に学ぶべきだ」と話している。
僕は、小林さんの意見の方を支持したいなぁ
http://www.gizmodo.jp/2012/01/google_53.html
Googleは「邪悪」になっていく? ユーザーの全データをサービス横断で利用 : ギズモード・ジャパン
僕は Google はほとんど使っていませんが、もし Google のサービスを使うとすると
Google さん
は、僕のことを世界中の誰よりも知っていることになるのかも・・・
富士通のノートPCの型番が国内モデルと海外モデルで紐づけしづらい気がします。
たとえば、CESで紹介されていたLIFEBOOK SH771ですが、国内2012年春モデルがSH76なので2012年夏モデルのUltrabookかと思っていたのですがその割には富士通の海外サイトでは普通に掲載されている状況に疑問を感じてSH771とSH76を比較してみました。
LIFEBOOK SH771の仕様はここ

LIFEBOOK SH76の情報はWebMartのカスタムモデル

の仕様を基にしています。
| | SH771 | SH76 |
| CPU | Core i7-2640M 2.8GHz or Core i5-2520M 2.5GHz | Core i7-2640M 2.8GHz or Core i5-2450M 2.5GHz |
| Display | 13.3inch SuperFine HD 1366x768pixels 300nits | 13.3インチ SuperFine / ノングレア 1366x768ドット |
| Modular Bay Devuce | Dual Layer DVD or Dual Layer Bly-Ray | Dual Layer DVD or Dual Layer Bly-Ray or 光学ドライブなし |
| Memory | 4GB DDR3 1333MHz or 8GB DDR3 1333MHz
max 8GB | 2GB DDR3 1333MHz or 4GB DDR3 1333MHz or 8GB DDR3 1333MHz
max 8GB |
| Hard Disk | 750GB (7,200rpm) 640GB (7,200rpm) 500GB (7,200rpm) 750GB (5,400rpm) 640GB (5,400rpm) 320GB (5,400rpm) 128GB SSD FDE | 750GB (5,400rpm) 640GB (5,400rpm) 320GB (5,400rpm) 128GB SSD 256GB SSD
|
| Battery | 6 cell Li-ion 67Wh 9.5h | バッテリL 72Wh 11.2h |
| Weight | 1.22kg (with weight saver option and SSD) | 1.22kg (光学ドライブなしで128SSD選択時) |
| Dimensions | 316x223x16.6~23.2 | 316x223x16.6~23.2 |
多少オプションの相違はありますが基本スペック上はまったく違いがないですね。
型番の付け方を統一した方がいいような気がするんですけどね~。
POWERUP HEROES (パワーアップヒーローズ)
自分がスーパーヒーローに変身して敵をやっつけるXBOX360 + Kinectのゲームです。
今回はこの「POWERUP HEROES」のレビューです。
まずキャラクターですが、いつも自分が使用しているアバターで戦うことができるのでなんか嬉しい。
攻撃はパンチ、キックとスーパアタックを織り交ぜて行います。
このヒーローは特殊なスーツを着ることによりスーツ固有のスーパアタックを使用することが可能になるのです。
スーツは敵を倒すことによって新たに入手可能で、さまざまスーパースーツを装着しなおすことでいろいろな技をくりだします。
なかにはウサギのキグルミ「ラビッツ」など変わったスーツもあり、スーパースーツを集めるのも楽しみの一つです。
スーパアタックは、「チェイン」と呼ばれる連続アタックによって相手に大きなダメージを与えることもできます
対戦相手はあまり強くないのでストレス発散にちょうど良いかも。
1時間くらいやってみましたが、毎回のことですが今回もキネクト痛に苦しみそうです。
詳細はこちらから
http://marketplace.xbox.com/ja-JP/Product/PowerUp-Heroes/66acd000-77fe-1000-9115-d8025553086b
※後日写真追加できるかな?
Sitecore (Sitecore CMS) はASP.NET上で動作するWeb Content Managementシステムです。
現時点でのバージョンはSitecore CMS 6.4.1で、Windows Server 2008/2008 R2を対象にして.NET Framework 2.0/3.0/3.5/4.0に対応しています。
一般的なCMSの
という機能に加えてSitecore CMSでは
- SEO(Search Engine Optimization)対策
- Webログ解析
- LPO(Landing Page Optimization)
などのパーソナライゼーション機能を有しています。
理想的な構築ができれば、利用者がたどり着きたい情報に検索エンジンからでも「探しやすく」「たどり着きやすく」つかっているデバイスで「見やすい」形で情報提供ができるサイトになるはずです。
何か情報にたどり着きたいとき、人はどのような行動をとりますか?
- 会社が分かっていれば、その会社のトップページ
- 製品が分かっていれば、検索エンジンで製品名を検索
- 漠然とならば、検索エンジンにキーワードを並べて絞り込みながら探す
検索エンジンの登場とその精度向上により以前のように自社のWebサイトに来てもらってからメニューをたどってという流れは作りづらいのではないでしょうか。
そのため一般的なCMSの機能で更新しやすくみやすいサイトというだけでは多くの同業他社の中から自社のページを開いてもらい、なおかつ、すぐ閉じられずに興味を引く内容を表示するというのは非常に重要な事なのです。
Sitecore CMSに興味を持った理由は、もちろん、ASP.NETの知識で機能拡張できるという点も大きいのですが、作りこみをしなくてもパーソナライゼーション機能を有しているという点です。
共通的に必須の部分が最初から備わっているならば、あとはお客様ニーズに合わせて基幹システムと連携したパーツを作りこんだり、キャンペーンコンテンツを代理店から受け取って表示する枠をつくっておいて必要に応じて表示したりなど想像的な部分に注力できるのではないかと考えています。
まだまだ実業務はおろか自分の個人サイトレベルでも自由自在にサイトを作れるというところまで至っていないSitecore CMSへの理解度ですが、徐々に情報をお出しできればと考えています。
IPv4 のアドレスは、日本では枯渇しました。で、IPv6 なのですが。。。ところで、IPv4 は、32ビット、429,4967,296種類を表せます(実際に使用可能なアドレスはそれ以下)。IPv6 は、これを128ビット、3.4028236692093846346337460743177e+38種類にした、と。
それはいいとして、IP 層の下に、Mac アドレスってありませんでしたっけ?Mac アドレスって、枯渇しないんですかねぇ?
え?48ビット、281,474,976,710,656種類あるので、IPv4ほど差し迫ってはいない、ですって?でも、業者に割り当てられるのは、24ビットで16,777,216種類ですよね?千六百七十七万、と。ミリオン ヒットを16回飛ばせるのか。しかも、機器に結びついているので、機器の破棄に伴って回収も可能、と(実際に出来るかどうかはともかく)。じゃぁ、大丈夫か。。。
そういえば、Mac アドレスって、固定じゃなく、変更出来る機器もありますよね?そして、「Wi-FiのMACアドレスはもはや住所と考えるしかない」なんて記事を見かけたのですが、これって、適当な Mac アドレスを入れると住所が出る、すなわち使われているアドレスかどうかがわかる、って事ですよね?で、その、Mac アドレスを変更出来る機器を、「存在することがわかったアドレス」に変更をすると、どうなるんでしょう?IP でのフィルターがされるから、他の所にデータが行っちゃうって事はない?他の所にもコピーされたデータが届くって事はないよね?
IPv6 とはまったく関係ないのですが、この辺のサービス提供者のやり方が気になる、というのがメインのエントリ。
ストリート ビューもそうですが、「公共の場から集められるデータだから良い」のでしょうか。例えば、通りを歩いているのは、「公共の場から集められるデータ」です。でも、ある日時にある場所にいることを知られる事がイヤな場合があります。ストリート ビューでは、そういう場合を、いつでも、どこからでも、誰にでも、検索して見える状態にする、という性質があります(マスキングはされますけど)。問題なのは、「公共の場で集めることができるデータを集める」事ではなく、それを「いつでも、どこからでも、誰にでも、検索して見ることが出来る状態にしている」ということ、それが「オプト インではなくオプト アウトとして提供されている」こと、「収集して公開されているということが周知されていない」ということ、ではないでしょうか。
そして、Wi-Fi による位置情報サービス。HTML5 の GeoLocation API で使用するサービスのひとつですが、ある地点で観測できた Mac アドレス(Google の場合は複数)を引き渡すと、その場所の位置情報(緯度、経度)が返ってきます。「ある地点で観測できた」という所が焦点です。無線 LAN の親機は、SSID と Mac アドレスを放送しています(ここで「放送」という用語を用いるのは正しくないが)。GPS 機能の付いた機器を用いて公道でこれを収集し、問い合わされた Mac アドレスから位置情報を逆引きして返すわけです。公道で収集できるデータだから集めて良い、ってものなんですか?私が最初に無線 LAN を導入したとき、SSID にファミリー ネームを設定しちゃいましたよ。でも、鉄筋コンクリート製の建物だったせいか、電波がまったく通らないので、すぐに有線に切り替えちゃいましたけどね。引っ越しをして、今度は大丈夫だろうと思ったけど、鉄骨製だからか、扉を閉めると通らない。「ブースター付き」とかいう機械を買ってきたのに。まぁ、子機もブースター付きってのを使えば何とか受信できるのと、引き回しの関係で有線に出来ないので、不便に思いながら使っているけど。で、新しい方の SSID は、デフォルトのまま使っていますが、Mac アドレスです。自分のもの以外の観測できる SSID は、メーカー名や機器名が SSID になっています。ほう?ということは、近所の人が同じメーカーや同じ機器を買ったら、SSID がかぶっちゃうわけですね。私が買ったものは、「Mac アドレスならかぶらないだろう」ということで Mac アドレスになっているのかな。で、こいつを、公道に放送したいとは思っていません。でも、漏れて行ってしまっていると思います。止める方法があるなら教えて欲しい。「家を金属板で覆え」って?そろそろ外壁を直さなきゃいけないので、その時、本気で考えようかしら???
なんてことを書いていたら、こんな記事も発見しましたよ→「WiFiのアクセスポイントが街中で増えることの功罪」。公衆 Wi-Fi が増えすぎると、かえって困った事態が発生すると。Rさん、喜ばしいことだけではないみたいですよ。(トラックバック:「自販機 Wi-Fi」)
プリンターのお話し。
直接会ったことのある方々にはお話ししているように、ここ数年、Windows から離れて Linux にかかりっきりです。プリンターに関わっているのですが、その為に、WinSpool.drv 等のプリンターに関わる API をいじらなくてはならないことも。基本、Windows じゃないのですけどね。でも、もう、C++、というか、Visual C++(Managed C++, C++/CLR 含む)は、いじりたくないです。何とか、C# でやっています。
で、プリンターの試験を行っていると、特定の条件で特定のファイルを何度も印刷することがあります。一般社団法人電子情報技術産業協会という協会があるのですが、そこから印刷における標準的なドキュメントが出ているので、それを印刷します。アプリケーションから印刷するとき、印刷ダイアログに「ファイルに出力する」というチェックボックスがあって、これをチェックしたときに出来る .prn ファイル。こいつは、スプーラーが貯め込んでいるファイルとほぼ同じで、ドライバーがプリンター用に作ったデータそのものです(他にスプーラー用の情報ファイルが出来るので、「ほぼ同じ」と表現した)。この .prn ファイルを作っておいて、ポイっと投げてやれば、いちいちアプリケーションを起動したり、印刷設定をし直したり、Microsoft Word だったら終了時に問い合わせがなくなっていいよね!!というのが狙い。ああ、ファイルは、Microsoft Excel、Microsoft PowerPoint、Microsoft Word、Adobe Reader 用のものがあります。それぞれ、別のアプリケーションで開かなきゃいけないのも、1つで事足りるよね!
やり方は、Windows GDI の、Printing and Print Spooler で定義されている、OpenPrinter 関数でプリンターを開き、StartDocPrinter 関数でこれからデータを投げることを通知して、WritePrinter 関数で書き込む、全部書き終わったら ClosePrinter 関数で閉じる、と。アプリケーション フォームには、ファイルを指定する方法と、プリンターを指定する方法を用意しておけばよい、と。そんなに難しいものではありませんね。チャチャっと作っちゃいましょう。
で、作ったのですが、欲が出てきた。プリンターとしての機能の試験をしているので、印刷指示をした後、プリンターが動かないと、プリンター(のファームウェア)が悪いのか、印刷指示が出来ていないのか、わからない(複数のファイルを交互に投げることがあるので、印刷ファイルを列挙するために ListView を使うと、クリックするところによって選択状態が外れてしまい、「印刷指示が出来ていない」という状態が出来てしまった)。プリンター フォルダーを表示していればわかりますが、そうでなくてもたくさん開いているウィンドウを、少なくしたい。ならば、プリンター一覧に、プリンター フォルダーで表示しているのと同じ内容を表示してやれば良いではないか。
ということで、情報を表示させます。EnumPrinters 関数は、PRINTER_INFO という構造体の配列を作って呼び出すと、そこへデータを放り込んでくれます。PRINTER_INFO 構造体は、1~9の9種類あるのですが、いくつかは廃止されています。EnumPrinters 関数に対して有効なのは、1, 2, 4, 5 の4種類です。プリンターの状態は、PRINTER_INFO_2 構造体(英語)に、Status として定義されています。こいつを拾い出しましょう。
という修正を施して、実行しました。Statu に0が返ってきています。USB で接続したプリンターの、USB ケーブルを抜きました。プリンター フォルダーでは、「オフライン」表示に変わりました。PRINTER_INFO_2 構造体は…0のままです。なんで?
Bing って回ったところ、どうも、ドライバーが正しい情報を返していないらしいです。なんてこったい!!そうすると、ちゃんと「オフライン」と表示されるプリンター フォルダーは、どこから情報を得ているんだろう?
ついでに書いておくと、WMI で、Win32_Printer にアクセスすると、同じように情報が取れます。HTML と組み合わせて Windows Sidebar Gadget にすれば、コンパクトにプリンターの状態を監視することも可能です。とはいえ、ネットワーク プリンターの場合、他の人が印刷しているのはわからないのですが。あ、それもドライバーがプリンターと通信していればわかるのか。Web Service on Devices に対応しているなら、デバイスに直接尋ねに行くから、必ず正しいステータスがわかるのね。
おっともうひとつ。上記方法では、EnumPrinters を実行したときのプリンターの状態しかわかりません。それで情報が取れるのを確認してから、FindFirstPrinterChangeNotification 関数などを使おうとしていたのですが、ドライバーが情報を返していないのなら、仕方ないですよね。
なんて原稿を用意した後、メールの整理をしていたら、2008年9月に、こんな問い合わせをしていた。なんてこったい、FindFirstPrinterChangeNotification 関数を使えだって!
[お問い合わせの概要]
メーカー提供のポートモニタに対して WMI の Win32_Printer:PrinterStatus を問い合わせると、印刷後 "Unknown"となり、標準の TCP/IP ポートモニタと異なるが、この原因を解明する方法、対処方法を知りたい。
[回答]
ポート モニタを含めて、スプーラ サービス内のステータスに依存して、WMI の Win32_Printer:PrinterStatus の値が異なることがございます。また、このようなスプーラ サービスのステータスは、拡張コンポーネントに依存性が高く、本件では、ポート モニタやランゲージ モニタに依存している可能性が高いと思われます。
具体的な例といたしまして、これらのプリント モニタは、少なくとも EndDocPort 関数内にて、SetJob 関数に以下のコマンドを指定する必要がございます。
ポート モニタ: JOB_CONTROL_SENT_TO_PRINTER
ランゲージ モニタ: JOB_CONTROL_LAST_PAGE_EJECTED
また、このコマンドの指定のタイミングや順番などに依存して、標準の TCP/IP ポートモニタとは異なる可能性がございます。併せまして、標準の TCP/IP ポートモニタでは、SNMP でプリンタのステータスを監視し、その状態をスプーラ サービスのステータスに反映するため、ステータスの差異が発生する可能性がございます。
続きまして、本件では、印刷が開始できる状態なのかどうかを判断するために、Win32_Printer:PrinterStatus を確認されているとお伺いいたしました。このステータスは、一般的なステータスに分類分けをされておりますが、細かなステータスをチェックすることができません。印刷が開始できる状態なのかどうかを判断は、プリンタに依存するステータスもあるため、プリンタの細かなステータスで、判断されたほうがよいかと存じ上げます。
そのような細かなステータスを取得する観点より、Win32_Printer:PrinterState は、スプーラ サービスから取得した情報 (PRINTER_INFO_6 構造体) の値となっておりますため、より詳細な状態をチェックすることが可能でございます。ただ、このプロパティは、obsolete であり将来的には、未サポートとなる可能性がございますことをご注意ください。
また、Win32 API とはなりますが、以下にご案内申し上げますサンプル コードにて、コントロールパネルの [プリンタと FAX] にて表示されるプリンタ キューの情報と同等な方法で、同等な情報が取得可能でございます。
Microsoft サポートオンライン「PrintMon.exe Demonstrates the Win32 Spooler API」
http://support.microsoft.com/kb/196805/en-us(英語)
※ Windows 9x/Me では、ポーリング形式
※ Windows 2000 以降では、イベント形式 (FindFirstPrinterChangeNotification/FindNextPrinterChangeNotification)
以上のとおりお伝えいたします。
やっとというかついにというか、 ODAC 11.2 Release 4 (11.2.0.3)がリリースされました。
日本オラクルのダウンロードサイトでは2012/01/25現在だと「ODAC 11.2 Release 3 (11.2.0.2.1)」ですがUS OTNからダウンロードできます。
11.2.0.3の新機能としては次の3点になります。
- ADO.NET Entity Framework and LINQ to Entities
- WCF Data Services and OData
- Implicit REF CURSOR Parameter Binding
Client 11.2.0.3から接続できるDBとしてはOracle Database 9i Release 2以降であれば接続可能です。
対応しているVisual StudioはVisual Studio 2010と.NET Framework 4となります(Entity Frameworkとしては4.1と4.2)。
ODP.NETでのEntity Frameworkの使い方は
http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51odt-453447.html?msgid=3-5804196843txt
に掲載されています。
iPhone とか Android とか Windows Phone などのアプリから印刷できる
モバイルプリンター
ってあるんだろうか?
お客さんの要望は iPhone なんだけど僕的には Windows Phone を使いたくて、開発担当は Android が使いたいというw
Windows Phone 使いたいなぁ・・・
昨年、時間を見つけてblogにアップしていたWindows Phone 7のアプリ作成エントリーをWebサイトの記事にまとめました。
「Windows Phone 7アプリを作成してみよう」
よかったらお立ち寄りください。
http://d.hatena.ne.jp/shi3z/20120124/1327364165
クォータニオン - UEI/ARC shi3zの日記
仕事中だというのに
ついつい
読みふけってしまった...
2/18 のわんくま同盟東京勉強会で「ステップバイステップで作る本格インストーラ(WiX編)」というのをやります。現在、msi-ml でネタ募集スレが立っています。根っこはこちら。
これから作らなければならないとか、作ってみたけど挫折した、あるいは作ってみたい(単なる興味本位)なんて人でも、実際に一つ作ってみて「こんな感じなのか。」というのが実感できるようなものにしたいと思っています。
もちろん、今まで両手でも数えきれないくらいインストーラを作ってきた!という人もOK。むしろそういう人は現地で手伝ってくださいw<おい!
実際のところどこまでやれるか全くわからないので、私も当日が楽しみです。
今回は、わんくまでも初めての形でのハンズオン形式で、マシンが必須です。持ち歩きの都合を考えると、ノートPCがいいと思いますが、デスクトップPCでもかまいません。ただし、その場合はモニターごと持参してください。
インストール対象アプリは MISAO(http://misao.codeplex.com/)。とはいえ、あくまでもサンプル(素材からは作れないので)なので、MISAOではなく、自作アプリや、社内ツールなど、個人的に作りたいものを持ってきてもらってもOKです。ただし、Windows用のデスクトップアプリ限定です。
もちろん、実際の業務アプリでも構いません(持ち出しに問題がないなら)し、WiXの代わりにInstallShield(ただしPro以上)でやってみたいなどもOKです。
実際、コードを手入力するのか、マウス操作主体で作業するかの違いを除けばほぼ同じものが作れます。もちろん個別の操作に関する質問なども答えられるものはその場で答えていきますよ。
お申し込みは、わんくま同盟 東京勉強会 #68 から。質問やネタなどは、msi-ml までどうぞ。
なお、現在わんくまサーバーが完全復旧できていないため、左上の「連絡をする」するからのメールは送信できませんのでご了承ください。
ネタ元:The wixtoolset.org online. & The new wixtoolset.org and weekly builds
wixtoolset.org という随分前から工事中だった新しいポータルサイトがようやくオープンし、それと一緒に Weekly Releases も再び始動したようです。
Weekly Releases のところに、「They are purged irregularly.」という表現があるのでいつまでもあると思うな。。。ということのようですので、プロジェクトで利用する場合は、必ずバックアップを自分で保持しておく必要があると思ったほうがいいでしょう。
バグトラックやMLは従来通り SourceForge で、マイルストーンリリースなどは codeplex で行うようです。
最終的には、wix.sourceforge.net を整理してここに集約させるのかな?
ところで。。。WeeklyRelase のフィードはどこ?<おい!
昨年11月に出たセキュリティのアドバイザリが本日(2012年1月23日)更新されて、Windows Mobile 6.x、Windows Phone 7 および Windows Phone 7.5向けのセキュリティー更新プログラムがリリースされたそうです。
「マイクロソフト セキュリティ アドバイザリ (2641690): 不正なデジタル証明書により、なりすましが行われる」
http://technet.microsoft.com/ja-jp/security/advisory/2641690
さて、私のIS12Tが更新されるのはいつのことやら……
こっちもまだ降ってこない><
「WindowsR Phone IS12T アップデート情報 2012年1月19日」
http://www.au.kddi.com/seihin/ichiran/smartphone/up_date/is12t/up_date_20120119.html
http://rocketnews24.com/2012/01/21/173455/
身体にまつわる10の勘違い 「体毛は剃ると濃くなる」「暗い場所での読書は目に悪い」など – ロケットニュース24(β)
この中にある
(3)毎日の睡眠時間は8時間必要である
の部分が気になってます。
実は、以前この話を聞いて、意識的に毎日 8 時間睡眠をとってみたことがあります。
その結果、3 日目に眠れなくなってしまいました。
ちなみに普段は 4~6 時間睡眠で、この方が自分にはあってるように思います。
・・・というか、これってみんな同じなんじゃないかと思ってるんですけど、実際どうなんですか?
「パワーアップ ヒーローズ」は 2012 年 1 月 19 日に発売された Xbox360 専用ソフトです。ジャンルはヒーロー格闘アクションです。Kinect 専用ソフトですので、プレイには別途 Kinect コントローラが必要になります。
他の Kinect タイトルでも多い手法ですが、操作するのは自身のアバターです。格闘方法としては、接近戦の攻防だけでなく、エネルギー波や衝撃波などを飛ばすこともできます。これらの能力は装備しているスーパースーツの種類によって異なるため、遊びの幅が広がります。アンロックできるスーパースーツは 20 種類にも及びます。
接近戦では、画面に指示されるモーションどおりに操作し攻防を広げます。対戦相手が接近戦を挑んできた時の防衛も同様となります。ファイターズ アンケージ風ですね。
パワーアップ ヒーローズでは他の格闘アクションにもあるようにチェインという概念があります。特筆すべき点としては、スーパーアタック (必殺技) をチェインするスーパーチェイン。さらにチェインすることでウルトラチェイン、ウルティメット チェインまで繋げることができます。このあたりの様子は公式のサイトからも見ることができます。
皆さんもぜひ、ヒーローになりきってプレイしてみてください。
関連リンク
※「Microsoft MVP 向け “パワーアップ ヒーローズ” レビューキャンペーンに参加し、本ソフトのレビューを行っています」
もうご存知の方も多いと思いますが、日本マイクロソフト デベロッパー&プラットフォーム統括本部 UX エバンジェリストの川西 裕幸さんが2012年1月20日(金)にお亡くなりになりました。
日曜日に行われたお通夜には、中さん、とっちゃん、私で参列させていただきました。
川西さんのお人柄が偲ばれるお通夜だったと思います。
私と川西さんの出会いがいつだったのか記憶が定かではありませんがTech EdかMVP関連のイベントであったのではないかと思います。
その後はわんくま勉強会でセッションをして頂いたり、去年の7月にHokuriku.NET Vol.7 in 福井でご一緒させていただいたり、12月のWindows Phone 7ハッカソンでご挨拶をさせて頂いたり、Windows Phone 7やKinectに興味をもってから川西さんのblogにお世話になりっぱなしだったりと、こちらの一方的な思いかもしれませんがその優しい笑顔も含め憧れの技術者のお一人でした。
ご冥福をお祈りいたします。
先日Twitter上でダウンエディションの話題があり、自分の認識と違いがあったので調べてみました。
「WindowsServer Enterprise」で「Standard」が使用できるとの話しで、私の認識ではダウンエディション権があるのは「DataCenter」のみでした。
実は仮想化が普及し始めたことが原因だとおもいますが、使用権について変更が加わっていました。それも結構前から…
ではいつから「EnterPrise」でもダウンエディションできるようになったかですが、詳細にはわかりませんでしたw。
しかし、製品使用権説明書に初めて変更内容が記載された時期はわかりましたので、更新が追加された月の若干前に変更が行われたものと思われます。
また、記載内容から、物理環境と仮想環境ではダウンエディションが可能になった時期が違ううようです。
2008/1に記載では仮想化環境の前提が外れています。
結論としては
仮想環境では2005年12月少し前
物理環境では2008年1月少し前から
ダウンエディション可能になったていたということのようです。
ライセンスは定期的にチェックが必要ですね。勉強不足でした。
※今回のように使用権は随時変更されます。実際に購入される、提案される場合は別途マイクロソフトに確認お願いします。
以下 Microsoft VolumeLicenseing 製品使用権説明書 (PUR)より抜粋
-------------------------------------------------------------------------------------------------------
マイクロソフト製品使用権説明書 (2005 年 12 月版)
P26
B. 特定の製品に関する例外規定と追加の条件
Windows Server 2003 R2 Enterprise Edition:
サーバー ソフトウェアのインスタンスの実行 割り当てる各ライセンスにつき、
? お客様は一度に、ライセンス取得済みのサーバー上で以下を実行することができます。
o 1つの物理的オペレーティング システム環境で、本サーバー ソフトウェアの1つのインスタンスを実行すること。
o 仮想的オペレーティング システム環境で、最大4つの本サーバー ソフトウェアのインスタンスを実行すること(1つの仮想的オペレーティング システム環境につき1つのインスタンスのみ)。お客様は、これらの仮想的オペレーティング システム環境のいずれにおいても、Enterprise Editionのインスタンスの代わりにStandard Editionのインスタンスを実行することができます。
--------------------------------------------------
マイクロソフト製品使用権説明書 (2008 年 1 月版)
P33~P34
Windows Server 2008 Enterprise および Windows Server 2008 Enterprise without Hyper-V
サーバー ソフトウェアのインスタンスの実行 割り当てられた各ライセンスにつき、お客様は以下が許諾されます。
・ お客様は一度に、ライセンス取得済みのサーバー上で以下を実行することができます。
o 1 つの物理的オペレーティング システム環境で、本サーバー ソフトウェアの 1 つのインスタンスを実行すること
o 仮想的オペレーティング システム環境で、最大 4 つの本サーバー ソフトウェアのインスタンスを実行すること (1つの仮想的オペレーティング システム環境につき 1 つのインスタンスのみ)
・ ライセンス取得済みのサーバー上で、任意のオペレーティング システム環境の Enterprise の代わりに Standard のインスタンスを実行することができます。
前回まででおよその形は出来上がりました。まぁいまどきのアプリってSilverlightとかだわなぁってことでSL、WP7から使えるようにライブラリをこさえてみようと思ったんですがうまくいかない。
WebClientで同期でとっちゃってるんでそりゃ駄目だわな。非同期に書き換えるとして。。。IEnumerableで返せん。。。Linq構文あきらめてただのWebClientの非同期サンプルにする?それは負けだろう。
…Rxだな。。。
とはいえRXで非同期をなんてサンプルはどこにでもある話。やるなら噂で聞いたIQbservableかなぁと漠然と思いながらneueさんのRxのライブラリ紹介とかを見ながらお勉強。どうせなら同じソースで動かしたいよねぇってことでRxを落としてくる。が、ここで問題発生。どうもWP7にはIQbservableがなさそうな予感。。。色々悩んだ結果以前の部分でIEnumerableを返してたのでTの部分を非同期リクエストの戻りであるIObservableを内包した形で返すことに。合わせてResult周りの型を変更。GourmetResult : ResultBase>な感じに。
ではプロジェクトのほうを整えることに。Coreに切りだしていた部分はそのまま使うのでリンクで追加。あ、そうそうWP7にはExpressionVisitorがないんですがMSDNのサイトにソースが全部あるので追加。プロバイダ周りは書き換えるのでコピーで追加しました。全体像してはこんな感じ。

PagingQueryProviderを書き換えていくことにします。肝としてはWebClientで動機リクエストしてたところをIObservable化するところってことですが@ITにずばりな感じの入門記事があったのでそれを参考に。
第1回 Reactive Extensionsの概要と利用方法
WebClientにDownloadStringAsyncってのが追加されてIObservableで返ってきますのでその後パースしてってところは前と同じ。
var req = WebRequest.Create(executeUrl);
var o = req.DownloadStringAsync().Select(_ =>
{
var element = XDocument.Parse(_);
var ns = element.Root.GetDefaultNamespace();
//エラーチェック
var error = element.Descendants(ns + "error").FirstOrDefault();
if (error != null) throw new InvalidQueryException(new Error(ns, error).Message);
//クエリー条件にマッチする、検索結果の全件数
this.limit = int.Parse(element.Descendants(ns + "results_available").FirstOrDefault().Value);
//このXMLに含まれる検索結果の件数クエリー条件にマッチする、検索結果の全件数
this.returnedCount = int.Parse(element.Descendants(ns + "results_returned").FirstOrDefault().Value);
//検索結果の開始位置
var resultStart = int.Parse(element.Descendants(ns + "results_start").FirstOrDefault().Value);
var collection = element.Descendants(ns + name);
//取得件数が指定されているなら補正する
if (takeCount.HasValue)
{
var endLimit = takeCount.Value + start;
this.limit = Math.Min(endLimit, this.limit);
}
return collection.Select(x => innerBuilder(x)).ToArray();
});
こんな感じです。パース後にDescendantsするとXElement[]になるんですが途中部分でサクッと変換はやりにくいので要素一個のファクトリメソッドを受け取るようにしておきました。(FuncなinnnerBuilderってやつです)これでIObservableって形になるのでこれを前回の結果のIEnumerableを内包した結果で返します。
継続部分をとる必要がありますが以前はIEnumerableだったので普通にConcatでした。今回はIObservableとIEnumerable>をつないで返すことに。これはEnumerable.Repeat(o, 1).Concat(GetResultCore(url))でおけ。
でとりだしの部分ですがIObservableとIEnumerable、配列が混在なのでちょっとややこしいですが分けて考えれば大丈夫。
var context = new HotpepperContext();
var query = (
from result in context.Gourmet
where result.keyword == this.textBox1.Text
select result).Take(100).First().Results.Concat();
var subscribe = (
from results in query
from shop in results
select shop)
.ObserveOnDispatcher()
.Subscribe(_ =>
{
count++;
this.textBlock1.Text = count.ToString();
this.listBox1.Items.Add(_);
});
こうなります。前半は以前と同様IQeryableを使ってるところ。IEnumerableを含んだ(Resultsがそれ)結果がひとつ返るのでFirstしてResultsをConcat。この操作でIEnumerable>がIObservableに平滑化されます。このまま続けて書いてもいいのですがここまではIQueryable、これからはIObservableという違いとT[]で返るのでSelectManyがわかりやすいように分けてクエリ構文で記載してみました。

感触ですがかなり簡単に取れるのでいい感じ。もろもろまとめて公開予定ですがひとまずPageQueryProviderのソースだけでも乗っけときますね。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Xml.Linq;
using System.Xml;
using System.Net;
using System.Reactive.Linq;
using System.IO;
namespace LinqToHotpepper
{
///
/// ファクトリクラス
///
public static class PagingQueryProvider
{
///
/// ファクトリメソッド
///
/// 発行されたAPIキー
/// リクエストURL
/// 抽出対象のXML要素名
/// 結果セットのファクトリ
/// 結果のファクトリ
public static PagingQueryProvider Create(string apiKey, string baseUrl, string name, Func<IEnumerable<IObservable>, T1> builder, Func<XElement, T2> innerBuilder)
{
return new PagingQueryProvider(apiKey, baseUrl, name, builder, innerBuilder, null);
}
///
/// ファクトリメソッド
///
/// 発行されたAPIキー
/// リクエストURL
/// 抽出対象のXML要素名
/// 結果のファクトリ
/// 結果セットのファクトリ
/// 要素から抽出を行うFinder
public static PagingQueryProvider Create(string apiKey, string baseUrl, string name, Func<IEnumerable<IObservable>, T1> builder, Func<XElement, T2> innerBuilder, EqualsFinder finder)
{
return new PagingQueryProvider(apiKey, baseUrl, name, builder, innerBuilder, finder);
}
}
public class PagingQueryProvider : QueryProviderBase
{
/// 発行されたAPIキー
private string key;
/// リクエストURL
private string baseUrl;
/// 要素から抽出を行うFinder
private EqualsFinder finder;
/// 抽出対象のXML要素名
private string name;
/// 結果セットのファクトリ
private Func<IEnumerable<IObservable>, T1> resultBuilder;
/// 結果セットのファクトリ
private Func<XElement, T2> innerBuilder;
/// 開始件数
private int start;
/// 取得中件数
private int index;
/// 取得終了件数
private int limit;
/// 取得時の戻り件数(初回リクエスト時の戻り件数)
private int returnedCount;
/// パラメータで指定された取得件数
private int? takeCount;
/// デフォルトの取得件数
private const int DEFAULT_COUNT = 30;
///
/// コンストラクタ
///
/// 発行されたAPIキー
/// リクエストURL
/// 抽出対象のXML要素名
/// 結果のファクトリ
/// 要素から抽出を行うFinder
public PagingQueryProvider(string apiKey, string baseUrl, string name, Func<IEnumerable<IObservable>, T1> builder, Func<XElement, T2> innerBuilder, EqualsFinder finder)
{
this.start = 0;
this.key = apiKey;
this.baseUrl = baseUrl;
this.name = name;
this.resultBuilder = builder;
this.innerBuilder = innerBuilder;
this.finder = finder;
}
protected override IEnumerable GetResult(Expression expression)
{
InnermostFinder innerFinder = new InnermostFinder();
var sb = new StringBuilder(baseUrl);
sb.AppendFormat("?key={0}", key);
if (finder != null)
{
MethodCallExpression whereExpression = innerFinder.GetInnermostWhere(expression);
if (whereExpression != null)
{
LambdaExpression lambdaExpression = (LambdaExpression)((UnaryExpression)(whereExpression.Arguments[1])).Operand;
// Send the lambda expression through the partial evaluator.
lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression);
finder.Expression = lambdaExpression.Body;
foreach (var item in finder.Results)
{
sb.AppendFormat("&{0}={1}", item.Key, item.Value);
}
}
}
MethodCallExpression skipExpression = innerFinder.GetInnermostSkip(expression);
if (skipExpression != null)
{
this.start = int.Parse(ExpressionTreeHelpers.GetValueFromExpression(skipExpression.Arguments[1]));
}
MethodCallExpression takeExpression = innerFinder.GetInnermostTake(expression);
if (takeExpression != null)
{
this.takeCount = int.Parse(ExpressionTreeHelpers.GetValueFromExpression(takeExpression.Arguments[1]));
}
var url = sb.ToString();
var executeUrl = string.Format("{0}&start={1}",url, start + 1);
if (takeCount.HasValue) executeUrl = string.Format("{0}&count={1}", executeUrl, takeCount.Value);
var req = WebRequest.Create(executeUrl);
var o = req.DownloadStringAsync().Select(_ =>
{
var element = XDocument.Parse(_);
var ns = element.Root.GetDefaultNamespace();
//エラーチェック
var error = element.Descendants(ns + "error").FirstOrDefault();
if (error != null) throw new InvalidQueryException(new Error(ns, error).Message);
//クエリー条件にマッチする、検索結果の全件数
this.limit = int.Parse(element.Descendants(ns + "results_available").FirstOrDefault().Value);
//このXMLに含まれる検索結果の件数クエリー条件にマッチする、検索結果の全件数
this.returnedCount = int.Parse(element.Descendants(ns + "results_returned").FirstOrDefault().Value);
//検索結果の開始位置
var resultStart = int.Parse(element.Descendants(ns + "results_start").FirstOrDefault().Value);
var collection = element.Descendants(ns + name);
//取得件数が指定されているなら補正する
if (takeCount.HasValue)
{
var endLimit = takeCount.Value + start;
this.limit = Math.Min(endLimit, this.limit);
}
return collection.Select(x => innerBuilder(x)).ToArray();
});
yield return resultBuilder(Enumerable.Repeat(o, 1).Concat(GetResultCore(url)));
}
///
/// 繰り返し部分の取得実体
///
///
///
private IEnumerable<IObservable> GetResultCore(string url)
{
//次回取得位置を初期化
index = start + returnedCount;
//取得ループ開始
while (true)
{
//欲しい件数が取れているなら終了
if (limit < index + 1) yield break;
var executeUrl = string.Format("{0}&start={1}", url, start + 1);
//残りカウントを取得
var leftCount = limit - (index + returnedCount);
//取得件数より小さければ取得件数を減らす
if (leftCount < returnedCount) executeUrl = string.Format("{0}&count={1}", executeUrl, leftCount);
var req = WebRequest.Create(executeUrl);
var o = req.DownloadStringAsync().Select(_ =>
{
var element = XDocument.Parse(_);
var ns = element.Root.GetDefaultNamespace();
//エラーチェック
var error = element.Descendants(ns + "error").FirstOrDefault();
if (error != null) throw new InvalidQueryException(new Error(ns, error).Message);
//クエリー条件にマッチする、検索結果の全件数
var total = element.Descendants(ns + "results_available").FirstOrDefault();
// このXMLに含まれる検索結果の件数クエリー条件にマッチする、検索結果の全件数
var returned = element.Descendants(ns + "results_returned").FirstOrDefault();
//結果がなければ終了
if (total == null || total.Value == "0" || returned == null || returned.Value == "0") Observable.Empty<XElement[]>();
var collection = element.Descendants(ns + name);
index += int.Parse(returned.Value);
return collection.Select(x => innerBuilder(x)).ToArray();
});
yield return o;
}
}
}
}
public static class WebRequestExtensions
{
public static IObservable<string> DownloadStringAsync(this WebRequest request)
{
return Observable.Defer(() => Observable.FromAsyncPattern<WebResponse>(
request.BeginGetResponse, request.EndGetResponse)()
.Select(res =>
{
using (var stream = res.GetResponseStream())
using (var sr = new StreamReader(stream))
{
return sr.ReadToEnd();
}
}));
}
}
コーディング量はそうないもののいい感じにWP7対応できました。
※ひとまず今までの一式。WP7位置情報とか簡単に取れて面白いかも。
昨年のハッカソンで時間が足りなくて作りこめなかった部分を入れ込んだ「今ココなう! for Windows Phone」がリリースされました。
Windows PhoneのGPSで取得した情報を「今ココなう!」のサーバーでシェアすることができます。
http://www.windowsphone.com/ja-JP/apps/146db262-addf-46f5-8111-63360f4fd04f

新年早々の自転車ロングランもこのアプリをお供にして道に迷わずに帰宅できました。

要望などあればhatsune[at]wankuma.comまでご連絡ください。
http://www.yomiuri.co.jp/world/news/20120119-OYT1T00583.htm
座礁船の船長「偶然ボートに落ちた」と供述 : 国際 : YOMIURI ONLINE(読売新聞)
偶然
こんなことが起こるなんて凄いなぁ。
救命ボートの上に落ちて、自分の意志に反して岸に運ばれてしまったのか・・・
ひっさしぶりに boost 触ってみた。
最新版 1.48.0 におもしろそげなコンテナ: flat族を見つけたのね。
標準の std::set(およびその一味)は連想コンテナの実装に二分木を使ってるんだが、
boost::container::flat_set(およびその一味)はベタなvectorを使ってる。
そのため要素の格納の際、左右の枝のためのポインタを要するstd::setより省メモリ。
要素の挿入にはそこそこの時間がかかるけど、
lookup(検索)はバイナリ・サーチが使え、二分木のトラバースよか高速との触れ込み。
試してみんべ:
#include <iostream>
#include <set>
#include <boost/container/flat_set.hpp>
#include <boost/chrono.hpp>
using namespace std;
using namespace boost::container;
using namespace boost::chrono;
int main() {
const int N = 1000000;
std::set<int> s;
flat_set<int> f;
// [0..N) を set/flat_setに挿入
for ( int i = 0; i < N; ++i ) {
s.insert(i);
f.insert(i);
}
system_clock::time_point start;
duration<double> sec;
// [0..N) を set から lookup
start = system_clock::now();
for ( int i = 0; i < N; ++i ) {
s.find(i);
}
sec = system_clock::now() - start;
std::cout << "set " << sec.count() << " seconds\n";
// [0..N) を flat_set から lookup
start = system_clock::now();
for ( int i = 0; i < N; ++i ) {
f.find(i);
}
sec = system_clock::now() - start;
std::cout << "flat_set " << sec.count() << " seconds\n";
}
実行結果:
set 0.069004 seconds
flat_set 0.0480028 seconds
ホンマや。確かに速い。
WiX でインストーラを書いていて一番大変なのがGUIDの生成。ファイルが1つとか2つならまだいいですが、コンポーネントが100とか200とかざらにあるのがデスクトップアプリです(某ソフトのインストーラは477もありました)。
インストーラの作成はInstallShieldだよ!って人はいいんですけど、そうじゃなくてVSにWiX入れてガリガリ書いてます!って人だと何が大変って、GUIDを用意するのが一番大変だったりします。
ということで、さっとセットするためのマクロ。
- Sub InsertGUID()
- If IsNothing(DTE.ActiveDocument) Then
- Beep()
- Return
- End If
- DTE.UndoContext.Open("InsertGUID")
- Dim newGUID As System.Guid = System.Guid.NewGuid()
- DirectCast(DTE.ActiveDocument.Selection, TextSelection).Text = newGUID.ToString().ToUpper()
- DTE.UndoContext.Close()
- End Sub
Sub InsertGUID()
If IsNothing(DTE.ActiveDocument) Then
Beep()
Return
End If
DTE.UndoContext.Open("InsertGUID")
Dim newGUID As System.Guid = System.Guid.NewGuid()
DirectCast(DTE.ActiveDocument.Selection, TextSelection).Text = newGUID.ToString().ToUpper()
DTE.UndoContext.Close()
End Sub
わずか10行(オブジェクトを宣言しないでそのままにすれば9行)ですが、これで開発効率はおそらく数億倍は上がります。<いいすぎ!
実際ほかのツールの利用と違ってクリップボードは変更されないし、UNDOも一発で戻るし、ショートカットに登録しておけば、1アクションでセットできるし。
ただ、問題がないわけではないんですよねー。VSのマクロって次のバージョンには入ってないっポイんですわ。。。
http://togetter.com/li/243785
ツイッターでケンカする時に絶対に勝てる必殺技 - Togetter
まさに必殺技
ですね
この人、最強です・・・
今仕事でASP.NET MVC3とEntity Frameworkを使っていまして。
EFで作ったコレクションとコレクションの比較をLINQで書いてみました。
contents.Where(_ => sites[0].Urls.Select(url => url.UrlString).Contains(_.Url, comp))
contentsってのはUrlフィールドを持つContentクラスの集合で、
sitesってのはUrlsというフィールドを持つSiteクラスの集合。
そしてUrlはUrlStringというフィールドを持つクラス。
ただしContent側のUrlはただのString(紛らわしい)
こいつをStartsWithで比較したかったので上記の様に書いてみた。
compはIEqualityComparerを実装したクラス。やってるのはただのStartsWith。
http://rocketnews24.com/2012/01/19/173649/
お茶とヤクザをミックスしたドリンク『チャクザ』が大人気 / でも何か間違えている件 – ロケットニュース24(β)
チャクザ
ってなんだろうか?
とか思っていたら、お茶とヤクザをミックスしているからチャクザということらしい・・・
なんで?www
なんでお茶とヤクザをミックスしてるの?www
チャクザってwwwww
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>netsh int tcp show global
アクティブ状態を照会しています...
TCP グローバル パラメーター
----------------------------------------------
Receive-Side Scaling 状態 : enabled
Chimney オフロード状態 : automatic
NetDMA 状態 : enabled
Direct Cache Acess (DCA) : disabled
受信ウィンドウ自動チューニング レベル : normal
アドオン輻輳制御プロバイダー : none
ECN 機能 : disabled
RFC 1323 タイムスタンプ : disabled
** 上の autotuninglevel 設定は、少なくとも 1 つのプロファイルのローカル/ポリシー
構成を
上書きするウィンドウ スケーリング ヒューリスティックの結果です。
C:\Windows\system32>netsh int tcp set global chimney=disabled
OK
C:\Windows\system32>netsh int tcp set global rss=disabled
OK
C:\Windows\system32>netsh int tcp set global netdma=disabled
OK
C:\Windows\system32>netsh int tcp show global
アクティブ状態を照会しています...
TCP グローバル パラメーター
----------------------------------------------
Receive-Side Scaling 状態 : disabled
Chimney オフロード状態 : disabled
NetDMA 状態 : disabled
Direct Cache Acess (DCA) : disabled
受信ウィンドウ自動チューニング レベル : normal
アドオン輻輳制御プロバイダー : none
ECN 機能 : disabled
RFC 1323 タイムスタンプ : disabled
** 上の autotuninglevel 設定は、少なくとも 1 つのプロファイルのローカル/ポリシー
構成を
上書きするウィンドウ スケーリング ヒューリスティックの結果です。
C:\Windows\system32>
ThinkPad X61の代替機がなかなか見つからなくて(というか2012上半期にでるであろう第二世代UltraBookが気になって)どうしようかと思っていたのですが、故障していたファンが修理部品として普通にとりよせできるという情報をもらったので早速取り寄せして交換してみました。
取り寄せにはFRU番号が必要ですがWebからダウンロードできる保守マニュアルに明記されています。
ThinkPad X60, X60s, X61, および X61s 保守マニュアル
X61のファンであればFRU番号は42X3805です。この番号が分かれば保守センター(043-350-8607)に電話してFRU番号を申告して申込用紙をFAXしてもらいます。
部品があれば3営業日で届くらしく、私の場合は水曜日の16時に申込用紙に必要事項を記載して入金記録を添付してFAXし、土曜日の10時にはとどきました。本当にすばらしいスピード感です。

電源とバッテリーを外す

HDDを外す

メモリカバーを外す

裏側のネジをほぼすべて外す

キーボードと表側のカバーを外す

裏面のネジが全部とれていれば手前にずらすような感じでキーボードが外れます。キーボードがはずれれば表側のカバーも手前にずらすようにして外すことができます。
無線LANユニットとの接続を外す

保守マニュアルには無線LANユニットを外す手順となっていますが、接続ケーブルを外すだけで十分です。どちらがどちらにつながっていたかが分かるように外す前に写真にとっておくとよいでしょう。
MDCを取り外す

MDCについても保守マニュアルには取り外す旨が書かれていますがコネクタを外すだけで充分です。
スピーカーケーブルを外します

DCinコネクタとRJ-11コネクタを外します。

分かりづらいですがHDDのコネクタ部の後ろあたりに電源をマザーボード上に接続するコネクタがあります。その隣のRJ-11コネクタとともに外しておきましょう、
マザーボードと液晶の接続ケーブルを外します。

液晶との接続ケーブルはねじ止めされていますのでネジを外した後にケーブルを外します。
ハードディスクサブカードを外します。


HDDコネクタ部分のカバーネジを2つ外してハードディスクサブカードをはずします。

被膜部分を取り外します。

マザーボードを筐体から外すために液晶ケーブル近くにあるネジを外します。
SDカードスロットのネジを外します、

SDカードスロットのところのネジもマザーボードを筐体に固定しているネジなのでここもはずします。
マザーボードを取り出す

ここまでの過程でやっと筐体からマザーボードが取り外せます。マザーボードが取り外せれば裏側についているファンのネジを緩められるます。
マザーボードからファンを取り外す

ファンのネジはCPUファンによくあるばね式の物ですので少し押し気味にしながら回すと外しやすいです。
取り付けるときも同様に押し付けるような感じでねじ込むといいでしょう。
あとはいままでの逆の手順で組み立てていけば完成です。