自作PCを6年ぶりにフルチェンジ(ただしストレージ除く)したのでメモ

Windows7の修復ディスクと、TrueImageと、それとネット民たちに感謝。

それまで使っていた自作フルタワーPCが、ケースでかくてすごい邪魔だったしLANケーブルとさよならしたかったし、そういえばなんか色々処理が遅い気がしてきたなー、と思い最新の小さいPCを買おうと決断したのか1ヶ月くらい前。
でも望むような既製品がなかったので渋々自作を決行しました。渋々、というのは自作にいつも非常~に時間がかかっていたので自作したくなかったから。自作は6年ぶり3度目。今回も3日くらい格闘しました。
いわゆる自作erではないので、これを読んでしまった人は以下お笑いください。

CPUの殻割りって何ぞや・・・

CPUのヒートスプレッダ?をはがして!?・・・ダイに液体金属塗ってヒートスプレッダを戻す??

そんな手法存在するんですね・・・楽しそうな殻割り動画も見ました。俺にはそこまでやる気がでません。

ちなみに今回は殻割り済みのcore i7 6700kをオークションで入手しました。PCの用途的には完全にオーバースペックだけど、一度でいいからハイエンド品を買いたかったんだ。

でもRyzenが発売されたり・・・微妙な時期に買ってしまいました。

OSが起動しない

先代PCは事情あってWindowsXPWindows7デュアルブート状態(XPは全く使わない)で、インストールしたドライブは物理的に別なのですが、WinXP入りドライブは廃棄するために今回フォーマットしました。

すると先代PCでWin7が起動できなくなり、俺は気絶しかけました。

原因は、WinXP入りドライブの方にbootmgrがあったのにフォーマットしてしまったから! そのあたりの仕組みをよく知らなかったわけですが・・・修復ディスクが(WinXP入りドライブを)何だか修復してくれました。

最終的には、修復ディスクからのコマンドプロンプトWinXP入りドライブからWin7入りドライブにbootmgrとBootフォルダを普通にコピーしたり、とりあえずbootrecを一通り実行したりで、何だか何とかWin7入りドライブ単独でOSが起動するようになりました。

参考

windows7windowsxpのマルチブート環境で、xpを削除する方法 - マイクロソフト コミュニティ
https://answers.microsoft.com/ja-jp/windows/forum/windows_7-update/windows7%E3%81%A8windowsxp%E3%81%AE%E3%83%9E/b17c36f5-6b38-43ea-8512-6e5fdedfdf67

ブートマネージャーを編集する | IT って難しいね
http://bemo-st.com/pc/wp/2015/09/09/598/

Windows XP から Windows 7 を起動してる場合に Windows 7 のドライブにMBRブートローダーを作成して起動する方法。 - いつものしらべてもでてこない
http://bannan.hatenadiary.jp/entry/2013/05/25/133253

ケースの3.5インチベイにHDDを入れられない

大切なデータの入ったHDDがケース取り付けられないだなんて気絶しかけましたが、はめ込み方の問題でした。

今回買ったのはRaijintekのMetisというMini-ITXのケースでして、天板に3.5インチベイがあって天板単独で分解できるのですが、「天板を分解してHDDはめてケースに取り付ける」ではなく「ケースに天板が取り付けられたままHDDをはめる」でした。でないとHDDのお尻が引っかかって天板を取り付けられません。クッソ・・・

OSが起動しない その2

先代PCで念入りに調整したWin7入りドライブを新PCに繋いで電源入れるもOSが起動せず、気絶しかけました。

マザボで必要なドライバを有効にしないといけないらしいです(詳しいことは何にもわかりませんが・・・)

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\以下の、 ・Aliide.sys ・Amdide.sys ・Atapi.sys ・Ataport.sys ・Cmdide.sys ・Intelide.sys ・Msahci.sys ・Pciide.sys ・Pciidex.sys ・Viaide.sys の「start」の値です。 「3」になっているものがあれば、全て「0」に書き換えます。 無い項目は、無視してください。 「ControlSet001」や「ControlSet002」が存在している場合は、念のためにそちらも同様に編集しておくといいと思います。

ひょっとして先代PCで新マザボのドライバをインストールしてからWin7入りドライブを付け替えていれば問題なかったのかも・・・?

ASRock Z170 Gaming-ITX/ac MiniITXマザーボード MB3480 Z170 Gaming-ITX/ac

ASRock Z170 Gaming-ITX/ac MiniITXマザーボード MB3480 Z170 Gaming-ITX/ac

参考

SSDのOS(Win7)や設定はそのままマザーボードを交換してみた | 自作DIYソーラーと太陽光発電で売電・節約・エコ人生
http://www.solar-make.com/personal-computer/motherboard-replacement-ssd/3032/

マザーボードを交換するとOSが起動しなくなるから注意!その原因と対策をご紹介。 | TRAVELING
http://saiut.com/windows/change_motherboar/

マザーボード交換で起動しないトラブル発生 (Win7): 晴れときどき更新中(ブログ)
http://kuze.tea-nifty.com/blog/2015/08/win7-1f76.html

OSが起動しない その3

マザボ付属のドライバインストールCDでドライバを一括インストールしたらOSが起動しなくなりました。

OS起動しない事件は3回とも1日の内に起きたので、この時ばかりは心が無となり気づいたらWin7クリーンインストールしていました。

正気?を取り戻しTrueImageWin7入りドライブを復元し、FusionDriveで古いドライバを削除することで新ドライバをインストールできるようになりました。

ちなみに先代PCはAMDで新PCはIntelなので、先代PCのドライバを削除していなかったのはそもそも自殺行為でした・・・

スリープからの復帰に失敗する

HaswellからC6 C7という電源状態が追加されて、電源ユニットがそれに対応していないとスリープの復帰に失敗するとのこと。

電源はCorsairのVX450Wという古いもの(ほぼ未使用なので今回流用)なので電源が原因と思い、一応BIOSでC6 C7を無効化したのですが、未だにスリープ復帰は失敗します。

まあ、どうせスリープは使わない(休止ばかり使う)のでこの件は放置しています・・・

参考

価格.com - 『スリープからの復帰で失敗(画像がモザイクになる)』 ASUS H170-PRO のクチコミ掲示板
http://bbs.kakaku.com/bbs/K0000808296/SortID=19343587/

意外に役だったもの

メモリのブリスターパックがホチキスで止められていて開封しにくいことしにくいこと。
こういう時にはりトルPROを持っていて本当よかったと感じます。

サンスター はりトル PRO S4765800

サンスター はりトル PRO S4765800

JMockitでprivateメソッドをモック化したいのにIllegalArgumentException: Invalid null value passed as argument って言われるんです

new NonStrictExpectations(Target.class) {{
    invoke(Target.class, "method", any);
}};

こう書いていたわけです。するとjava.lang.IllegalArgumentException: Invalid null value passed as argument 0って言われるんです。invoke(Target.class, "othermethod", anyString)だと問題ないのに。

JMockit初めて使うしノリがまだ分からないし、その場は諦めてしまった。

理由は単純で、このinvokeはnullでない引数しか受けられないのにanyはnullだから起こっているわけですね。

class Target {
    public static void main() {
        private1("1");
        private2(new StringBuffer("2"));
    }

    private static void private1(String string) {
        throw new RuntimeException();
    }

    private static void private2(StringBuffer string) {
        throw new RuntimeException();
    }
}

public class JMockitSample {
    @Test
    public void 対象メソッドのみテスト1() {
        new NonStrictExpectations(Target.class) {{ // partial mockにしないとテスト対象すらモック化されてしまう
            invoke(Target.class, "private1", anyString);
            invoke(Target.class, "private2", new Class<?>[]{StringBuffer.class}, any); // anyはnullのためパラメータの型を指定しなければならない
        }
        };

        Target.main();
    }
    @Test
    public void 対象メソッドのみテスト2(
            // privateメソッドはどうせ静的にメソッド名を指定するしかないからこっちの方が楽
            @Mocked("private\\d") Target subject
            ) {
        Target.main();
    }
}

HTML5 DnDでハマってしまったんです

うん、基礎知識が足りないんでしょうね。。 これで動く。

<div id="drag">
  <div draggable="true">a</div>
  <div draggable="true">b</div>
  <div draggable="true">c</div>
</div>
$("#drag div").on("dragstart",  function(ev){
//  ev.preventDefault();
  console.log("dragstart:"+$(ev.currentTarget).text());
  ev.originalEvent.dataTransfer.setData("text", $(ev.currentTarget).text());
});
$("#drag div").on("dragover",  function(ev){
  if (ev.preventDefault) {
    ev.preventDefault();
  }
});
$("#drag div").on("drop",  function(ev){
  if (ev.stopPropagation) {
    ev.stopPropagation();
  }
  $(ev.currentTarget).text(ev.originalEvent.dataTransfer.getData("text"));
});

参考

iPad(iOS7)のSafariでなんか画面下に余白ができるんです

iPad mini(iOS 7.1.1)のSafariがlandscapeだとなんでか画面下部に余白ができるんです。たぶん20px。

window.innerHeightが672。これはいい。 でも$("body")[0].offsetHeightが690。これはない。さらにdocument.documentElement.clientHeightが691、そしてwindow.outerHeightが692。

portraitだとここまで変ではないのできっと事件だと思ってそこに焦点絞って調べたところ、

iPad(iOS7.0.4)のランドスケープモードで height: 100% だとバグる | girigiribauer.com

こちらで紹介されている検証サイトを使うとたしかにBUGGYってなる。

対策は

css - iOS 7 iPad Safari Landscape innerHeight/outerHeight layout issue - Stack Overflow

この記事を参考にして

@media all and (orientation: landscape) {
  html.ipad.ios7 > body {
    position: fixed;
    height: 672px !important;
    width: 100%;
  }
}

こうして

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
  $('html').addClass('ipad ios7');
}

こうすると余白が出ないようになった。

buttom: 0があると何も表示されなくなるから削除した。

2014-05-27追記 landscapeでロック画面を解除すると症状が悪化することがあるからやっぱり放っといた方がよさげ。。

jQuery MobileのEventの発生順

ちょっと自分でやってみた

<!DOCTYPE html>
<html>
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore.js"></script>

  <script type="text/javascript">
    function l(s) {
      if (s.target) {
        console.log("[log]["+s.type+"]"+s.target.tagName+(s.target.id ? "#"+s.target.id : "")+_(s.target.classList).map(function(c){return "."+c;}).join(""));
      } else {
        console.log("[log]"+s);
      }
    };
    $(document).on("pagebeforechange", function(ev) {l(ev);});
    $(document).on("pagebeforecreate", function(ev) {l(ev);});
    $(document).on("pagebeforehide", function(ev) {l(ev);});
    $(document).on("pagebeforeload", function(ev) {l(ev);});
    $(document).on("pagebeforeshow", function(ev) {l(ev);});
    $(document).on("pagechange", function(ev) {l(ev);});
    $(document).on("pagecreate", function(ev) {l(ev);});
    $(document).on("pagehide", function(ev) {l(ev);});
    $(document).on("pageinit", function(ev) {l(ev);});
    $(document).on("pageload", function(ev) {l(ev);});
    $(document).on("pageremove", function(ev) {l(ev);});
    $(document).on("pageshow", function(ev) {l(ev);});

    $(document).on("mobileinit", function(){
      $.mobile.hashListeningEnabled = false;
      $.mobile.linkBindingEnabled = false;
      $.mobile.ajaxEnabled = false;
      $.mobile.autoInitializePage = false;
      $.mobile.page.prototype.options.domCache = false;

      $.mobile.pushStatueEnabled = false;
      $.mobile.page.prototype.options.degradeInputs.date = true;
    });

    window.onload = function(){
      l("$.mobile.initializePage");
      $.mobile.initializePage(); // $.mobile.autoInitializePage = falseにしているので
      l("$.mobile.initializePage:called");
    };

    $(document).on("click", "button", function(ev){
      var target = $(ev.target).parents("[data-role=page]").attr("id") == "main"?"sub":"main"
      l("$.mobile.changePage");
      $.mobile.changePage("#"+target,{changeHash: false, role: "page"});
      l("$.mobile.changePage:called");
    });
  </script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-mobile/1.3.2/jquery.mobile.js"></script>
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/jquery-mobile/1.3.2/jquery.mobile.css"></script>
</head>
<body>
  <div data-role="page" id="main">
    <div data-role="context">
      <a data-role="button" href="#sub">hello jQM</a>
      <button>hello jQM</button>
    </div>
  </div>
  <div data-role="page" id="sub">
    <div data-role="context">
      <a data-role="button" href="#main">hello jQM sub</a>
      <button>hello jQM sub</button>
    </div>
  </div>
</body>
</html>
[log]$.mobile.initializePage jqm_event.html:12
[log][pagebeforechange]BODY.ui-mobile-viewport jqm_event.html:10
[log][pagebeforecreate]DIV#main jqm_event.html:10
[log][pagecreate]DIV#main.ui-page.ui-body-c jqm_event.html:10
[log][pageinit]DIV#main.ui-page.ui-body-c jqm_event.html:10
[log][pagebeforeshow]DIV#main.ui-page.ui-body-c jqm_event.html:10
event.returnValue is deprecated. Please use the standard event.preventDefault() instead. jquery.js:3345
[log][pageshow]DIV#main.ui-page.ui-body-c.ui-page-active jqm_event.html:10
[log][pagechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log]$.mobile.initializePage:called jqm_event.html:12
[log]$.mobile.changePage jqm_event.html:12
[log][pagebeforechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log][pagebeforecreate]DIV#sub jqm_event.html:10
[log][pagecreate]DIV#sub.ui-page.ui-body-c jqm_event.html:10
[log][pageinit]DIV#sub.ui-page.ui-body-c jqm_event.html:10
[log][pagebeforechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log][pagebeforehide]DIV#main.ui-page.ui-body-c.ui-page-active jqm_event.html:10
[log][pagebeforeshow]DIV#sub.ui-page.ui-body-c jqm_event.html:10
[log]$.mobile.changePage:called jqm_event.html:12
[log][pagehide]DIV#main.ui-page.ui-body-c jqm_event.html:10
[log][pageshow]DIV#sub.ui-page.ui-body-c.ui-page-active jqm_event.html:10
[log][pagechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log]$.mobile.changePage jqm_event.html:12
[log][pagebeforechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log][pagebeforechange]BODY.ui-mobile-viewport.ui-overlay-c jqm_event.html:10
[log][pagebeforehide]DIV#sub.ui-page.ui-body-c.ui-page-active jqm_event.html:10
[log][pagebeforeshow]DIV#main.ui-page.ui-body-c jqm_event.html:10
[log]$.mobile.changePage:called jqm_event.html:12
[log][pagehide]DIV#sub.ui-page.ui-body-c jqm_event.html:10
[log][pageshow]DIV#main.ui-page.ui-body-c.ui-page-active jqm_event.html:10
[log][pagechange]BODY.ui-mobile-viewport.ui-overlay-c 

ソースまで見てないけど$.mobile.initializePageはpagechangeまで同期で、$.mobile.changePageはpagebeforeshowまでが同期でpagehide/pageshow/pagechangeは非同期で発生するっぽい。

参考

グローバル設定 | jQuery Mobile 1.1.0 日本語リファレンス

Backbone.Model/Collectionのメソッドとして利用できるUnderscore.jsのメソッド

sortBy,map,pluck,filter,groupBy,pick.omitとか使える。いくつか試してみた。

backbone.js v1.0.0

function l(s) {console.log(s)};
function a(s) {alert(s)};
l('Underscore in Backbone.Collection');

var coll = new Backbone.Collection();
coll.add([
    {id: 0, name: 'taro', age: 20, sex: 'male'}
    ,{id: 1, name: 'jiro', age: 10, sex: 'male'}
    ,{id: 2, name: 'hanako', age: 11, sex: 'female'}
    ,{id: 3, name: 'kayo', age: 21, sex: 'female'}
]);

coll.forEach(function(model){
    l(JSON.stringify(model));
});

var sorted = coll.sortBy(function(model){
    return model.get('age');
});
var mapped = new Backbone.Collection(sorted).map(function(model){
    return {id: model.get('id'), name: model.get('name') + ',yamada', sex: model.get('sex')};
});

var plucked = new Backbone.Collection(mapped).pluck('name');
//ageの昇順になってnameにyamadaが追加されてnameだけが抜き出されている
l(JSON.stringify(plucked));

var grouped = new Backbone.Collection(mapped).groupBy('sex');
l(JSON.stringify(grouped.male));

//いちいちnew Backbone.Collection(array)は面倒なのでchainする
l(
    coll.chain()
    .filter(function(model){return model.get('age') <= 20;})
    .sortBy(function(model){return model.get('age')})
    .map(function(model){
        return {id: model.get('id'), name: model.get('name') + ',yamada', sex: model.get('sex')}
    })
    .pluck('name')
    .value()
);//groupByは特殊でできなかった

l('Underscore in Backbone.Model');

l(coll.get(0).pick(['name','age', 'sex']));
l(coll.get(0).omit(['id','sex']));