[IME] Management Studio で、IME が日本語入力に勝手に変わる

SQL Server の Management Studio で、クエリを実行した後に IME が勝手に日本語入力に変わってしまうことがある。IME の相性かとも思うが、原因は不明で、Management Studio の再起動しかないらしい。
2014 になった今でも発生し続けるバグのような印象だ。

Management Studioでストアドを編集後、実行するとIMEが勝手にONになる。 - msdn
https://social.msdn.microsoft.com/Forums/sqlserver/ja-JP/559e4757-f601-486d-b2bb-3e04a3640483/management-studioimeon?forum=sqlserverja

[ASP.NET] クッキーレス・セッションが消える

やや枯れた話題であるが、ASP.NET アプリケーションにおいてクッキーレス・セッション機能を使用している場合に、セッションが消えてしまうことがあったので調べてみた。
結論から言うと、そもそも ASP.NET アプリケーションは、URL の大文字と小文字を区別するらしいので、相対パスでアドレスが厳密に一致していないと、画面は遷移するもののセッションが消えてしまうという挙動を見せる。

Cookieless Session State May Be Lost in ASP.NET Applications

機械翻訳版
http://support.microsoft.com/KB/828330

再現手順としては、以下のような例を挙げている。
http://localhost/WebApplication1/(uwvgovu0hljrmdqcl1aajf2f)/WebForm1.aspx

http://localhost/WEBAPPLICATION1/(uwvgovu0hljrmdqcl1aajf2f)/WebForm1.aspx
※ セッションが消える。

しかし、WebForm1.aspx を、webform1.aspx としてアクセスする場合にも同様にセッションが消える。

[ASP.NET] This application is currently offline.

This application is currently offline. To enable the application, remove the app_offline.htm file from the application root directory.

ルートに app_offline.htm ファイルがあると、アプリケーションが開始できない。

App_Offline.htm ファイルは、Web アプリケーションを一時的に停止するための特殊ファイルであり、このファイルがあるとデバッグもできなくなってしまう。

[ASP.NET]Webアプリケーションを一時的に停止するには?[2.0のみ]- @IT
http://www.atmarkit.co.jp/fdotnet/dotnettips/684appoffline/appoffline.html

[C#] ArrayList を string.Join で文字列結合する

ArrayList にセットされている文字列を、カンマ区切りの文字列として出力したい場合、foreach で回すのもいいのだが、string.Join メソッドを使用した方がスマートに出力できる。
ArrayList arr = new ArrayList();
arr.Add("山口太郎");
arr.Add("山田次郎");
arr.Add("山品三郎");
string s =  string.Join(",",(string[])arr.ToArray(typeof(string)));
// 山口太郎,山田次郎,山品三郎
Console.WriteLine(s);
あえて ArrayList を使用しなくても良いが、古いソースを改修する場合などのためのメモ。

[C#] SqlCommand.ExecuteScalar の戻り値が Null

あまり意識していなかったのだが、少々ハマった。
SqlCommand.ExecuteScalar メソッド「クエリを実行し、そのクエリが返す結果セットの最初の行にある最初の列を返します」とある。SQL でカウントなど の集計値を取る場合に使うことがあるが、サンプルを見ると、以下のようになっている。
 cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
 Int32 count = (Int32) cmd.ExecuteScalar();
しかし、結果セットがない場合(レコード件数ゼロ)、上記の式だと Int に変換できずに System.NullReferenceException (オブジェクト参照がオブジェクト インスタンスに設定されていません)が発生する。
Int32 count = (Int32) cmd.ExecuteScalar();
cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
object value = cmd.ExecuteScalar();
if (firstColumn != null) {
  count = Convert.ToInt32(value);
}
クエリ次第なところがあるのだろうが、やはり一旦チェックは行ったほうが良いのではないか?

[C#] StringBuilder の AppendLine の終端文字列

StringBuilder の AppendLine メソッドは、ログ出力等の人の目で確認する場合に見やすく出力させたい場合によく使用されるが、これはメソッドが \r\n を自動的に追加してくれるもので、最後の文字列を何かしたい場合は気をつけなければならない。
var sb = new StringBuilder();
sb.AppendLine("AAAA,");
sb.AppendLine("BBBB,");
sb.AppendLine("CCCC,");
// "AAAA,\r\nBBBB,\r\nCCCC,\r\n"
var val = sb.ToString().TrimEnd(',');

var sb2 = new StringBuilder();
sb2.AppendLine("AAAA,");
sb2.AppendLine("BBBB,");
sb2.AppendLine("CCCC");
sb2.Append(",");
// "AAAA,\r\nBBBB,\r\nCCCC\r\n"
var val2 = sb2.ToString().TrimEnd(',');
改行コードが必要いなら、String.Join メソッドで連結したほうがスマートだが、改行コード付きとなると自分で改行するしかないか…。
見た目はきれいに出力してくれるのだがね。
var lst = new List();
lst.Add("AAAA");
lst.Add("BBBB");
lst.Add("CCCC");
// "AAAA,BBBB,CCCC"
var val3 = string.Join(",", lst);

[C#] StringBuilder の数値計算

StringBuilder.Append メソッドを使用して文字列を連結する際に、引数に数値型が含まれている場合の挙動には注意を払う必要がある。
int price = 10000;
int tax = 800;

StringBuilder sb = new StringBuilder();
sb.AppendLine("合計金額 = " + price + tax);
sb.AppendLine("消費税 = " + price * 0.08);

// 合計金額 = 10000800
// 消費税 = 800
Console.WriteLine(sb.ToString());

文字型への変換が必要だと思われるが、プラス(+) を使用すると文字列として連結される。しかし、他の演算子を使用した場合は計算後の結果が文字列として連結される。
結果ですぐに気づくだろうが、注意しなければならない。

[IIS7] アプリケーションプールをコマンドでリサイクルする

IIS7 から用意された Appcmd.exe により、コマンドから様々な操作を行うことができるようになった。以下の例では DefaultAppPool をリサイクルしている。

appcmd recycle apppool /apppool.name:"DefaultAppPool"

注意点は以下のとおり。

  1. コマンドプロンプトは管理者権限で実行すること(バッチファイルももちろん同じ)。
  2. name: の後ろにアプリケーションプール名を指定するのだが、ダブルクォーテーション ( " ) で囲まなければいけない。

他にも色々と管理上便利なコマンドが用意されている。

Appcmd.exe - TechNet
http://technet.microsoft.com/ja-jp/library/cc772200%28v=ws.10%29.aspx

[Google Chrome] 本体の場所

Google Chrome は Program Files にインストールされていないと思っていたのだが、バージョン 36 移行は 行儀よく Program Files にインストールするようだ。

Windows 7
C:\Users\Username\AppData\Local\Google\
Windows 8 や最近のバージョン
C:\Program Files (x86)\Google\Application\

[ASP.NET] Web サーバーでデバッグを開始できません

Web サーバーでデバッグを開始できません。統合 Windows 認証が無効になっているため、デバッグに失敗しました。詳細については、ヘルプを参照してください。

ASP.NET 2.0 のレガシーなアプリケーションをデバッグしようとしたら、いつか見たことがあるような悲しいダイアログが出る。以下を確認後、デバッグできるようになった。

Windows 認証の確認

そもそも Windows 認証が有効であるか確認。
  • コントロールパネル - プログラムと機能
  • Windows の機能の有効化または無効化
  • インターネットインフォメーションサービス - World Wide Web サービス - セキュリティ - Windows

IIS の設定

  • コントロールパネル - 管理ツール - インターネット インフォメーション サービス (IIS) マネージャー
  • 対象となるアプリケーションの 「認証」
  • Windows 認証を「有効」にする。

環境 : Windows 7, IIS 7.5

[C#] String.Split メソッドで空白データを除外する


String.Split メソッドに StringSplitOptions 引数を指定すると、空の配列要素が除外される。しかし、実際には空文字で構成されたデータを除外することができない。
ここでいう空の配列要素とは、あくまで区切り文字が連続で続いていたケースのみを指すのだ。

完全に除去したいのなら、ラムダを使用すると一行で消せる。
var ret1 = mail.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
// [1] test1@exsample.com
// [2]
// [3] test2@exsample.com

var ret2 = mail.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x));
// [1] test1@exsample.com
// [2] test2@exsample.com

// char で区切り文字を指定すれば、そもそもオプションはいらない。
var ret3 = mail.Split(new char[] { ';' }).Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x));
// [1] test1@exsample.com
// [2] test2@exsample.com 

String.Split メソッド
http://msdn.microsoft.com/ja-jp/library/System.String.Split(v=vs.110).aspx

[Explzh 64bit] .tar.xz ファイルを解凍する


SourceForge にある圧縮ファイルでよく使用されている .tar 形式を Explzh で解凍するためのメモ。
Explzh は tar ファイルの解凍もできるのだが、[メニュー] - [アーカイバ DLL の自動ダウンロード] を行ってもエラーが出るだけで、手動で DLL を導入しなければならない。

DLL 自体は、以下のウェブサイトで配布されている方がいるのでそれを使用する。

綾川的趣味之接続集
http://homepage1.nifty.com/Ayakawa/index.html
[Software] -> [tar64.dll ver 2.42 私家版]

ダウンロードした tar64.dll を、C:\Windows\System32 フォルダへコピーする。
(実は、C:\Program Files\Explzh へコピーしても動作する。あまり好ましくないと思うが……)

Explzh for Windows
http://www.ponsoftware.com/

[Explzh] 圧縮後の拡張子

"Explzh for Windows" で圧縮を行った際に、圧縮後の拡張子が小文字になったり大文字になったりと意味不明な挙動を見せるのだが、試しに検証してみると、圧縮対象のファイル名によって法則があるようだ。

小文字の拡張子になるケース

圧縮しようとするファイル名がすべて小文字。 2 文字目が小文字。
  • test1.txt → test1.zip
  • TeEST4.txt → TeEST4.zip

大文字の拡張子になるケース

圧縮しようとするファイル名がすべて大文字。 2 文字目が小文字。

  • TEST2.txt → TEST2.ZIP
  • tEST3.txt → tEST3.ZIP
複数のファイルを圧縮する際には複雑な仕様になっていそうだが、とりあえず元のファイル名によって拡張子が変わるらしい。圧縮後に自分で拡張子を変更すれば良いだけの話だが、はじめから固定で指定できるようになっているといいと思う。

Explzh
http://www.ponsoftware.com

[C#] DataRow から値を取得する(タイプセーフ)。

DataRow.Field は、.NET Framework 3.5 で拡張されたメソッドである。
DataRow といえば、アクセスする際に毎回型変換を明示的に書いていたものだが、Field メソッドを死傷することで、明示的に型を指定してアクセすることができる。
また、最大の違いは NULL 許容型がサポートされたこと。これにより取得したオブジェクトの中身が NULL であった場合でも長々と NULL チェックを書かなくても良くなった。セットした後の値の扱いは今までどおり注意を払う必要があるが、従来よりもスマートな書き方ができるようになったと思う。
DataTable dt = new DataTable();
// なんかデータ取得。

foreach (DataRow dr in dt.Rows)
{    
    // 従来までの書き方。
    string sHogeOld = (string)dr["HOGE"];
    // 値型は変換できない場合は落ちる。
    int iHogeOld = (int)dr["HOGEE"];

    string sHoge = dr.Field<string>("HOGE");
    // 値型でも、NULL 許容型にしておけば、いきなり落ちることはない。
    int? iHoge = dr.Field<int>("HOGEE");
}

DataRow.Field メソッド | msdn
http://msdn.microsoft.com/ja-jp/library/system.data.datarow.field%28v=vs.90%29.aspx

{SQL Server] 日付を曜日に変換する


日付から曜日を求めるには、DATENAME 関数を使用する。引数として正式には WEEKDAY を渡すのだが、これは DW や W だけでも良い。
結果は "曜日" と付くので、文字列を置換すると曜日のみ取得できる。
SELECT
 DATENAME(W, GETDATE()) AS 曜日
 ,DATENAME(DW, GETDATE()) AS 曜日
 ,DATENAME(WEEKDAY, GETDATE()) AS 曜日
 ,REPLACE(DATENAME(W, GETDATE()), '曜日', '') AS 曜日

[Opera] Chrome の拡張機能を使う


Opera はマイナーなブラウザではあるが、アドオンのひとつである Download Chrome Extension をインストールすると、なんと Chrome の拡張機能が使用できるようになる。 

Download Chrome Extension https://addons.opera.com/ja/extensions/details/download-chrome-extension-9/?display=en

インストールすると、Google Chrome の拡張機能ページの [CHROMEに追加] ボタンが、赤くなり、Opera にインストールできるようになる……のだが、Opera 26 では、Chrome ウェブストアからのリンクから表示させたアプリにはボタンが消えてしまっている。


検索をして、直接アプリを表示させた場合はボタンが出る。
いずれ解消されるのだろうが、Chrome の拡張機能が利用可能というのはかなり強力だ。


[ASP.NET] CSV ファイルをダウンロードさせる。

ASP.NET で CSV ファイルを作成してダウンロードさせるメモ。
// 適当な CSV フォーマット
var csvContents = new List() { "名前,ポイント" };
csvContents.Add("\"Noah\",\"4,090\"");
csvContents.Add("\"Liam\",\"90\"");
csvContents.Add("\"Sophia\",\"4,011\"");
csvContents.Add("\"Emma\",\"9,801\"");
var outputPath = @"d:\CsvSample.csv";

// ファイルがなくても OK
File.Delete(outputPath);
using (var writer = new StreamWriter(outputPath, true, Encoding.Default))
{
    // TODO: 例外処理を書く
    writer.WriteLine(string.Join("\r\n", csvContents));
}

// ダウンロード
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=CsvSample.csv");
Response.Flush();
Response.WriteFile(outputPath);
Response.End();
VB.NET の場合は以下のとおり。
'適当な CSV フォーマット
Dim csvContents = New List(Of String)(New String() {"名前,ポイント"})
csvContents.Add("""Noah"",""4,090""")
csvContents.Add("""Liam"",""90""")
csvContents.Add("""Sophia"",""4,011""")
csvContents.Add("""Emma"",""9,801""")

Dim outputPath = "d:\\CsvSample.csv"
' ファイルがなくても OK
File.Delete(outputPath)

Using writer As New StreamWriter(outputPath, False, Encoding.Default)
    writer.WriteLine(String.Join(Environment.NewLine, csvContents))
End Using

' ダウンロード
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment; filename=CsvSampleVb.csv")
Response.Flush()
Response.WriteFile(outputPath)
Response.End()
出力された CSV ファイルを Excel で開いた場合。

[Excel] 金額等のカンマ付きの値を正しく表示させる

商品,値段
冷凍青汁,100
サービス10,000円チケット,10000

Excel で、「10,000円」などが含まれる CSV ファイルを何も考えずに開くと崩れてしまう。TSV を使うという手もあるが、" (ダブルクォーテーション) でくくってあげるだけで正しく表示される。" で囲むほうが確実だ。

商品,値段
"冷凍青汁",100
"サービス10,000円チケット",10000

Excel の例は上記のとおりだが、CSV にも仕様がある。

CSVファイルの一般的書式 (RFC4180 日本語訳)
http://www.kasai.fm/wiki/rfc4180jp

[SQL Server] 列を CSV として出力する

テーブルをリレーションする際に、ある ID から取得した結果を一行にまとめて結合させたい場合、FOR XML を使う。これにより、結果セットを CSV に整形した結果を一行にまとめて表示させることも可能。

Classes

Students

FOR XML は、取得した項目に区切り文字を連結させて使用する。以下は、何も考えないで連結するパターン。値の終端にもカンマが付いてしまっている。
SELECT
 C.Code AS クラスコード
 ,C.Name AS クラス名
 ,(SELECT S.FirstName + ',' FROM Students AS S WHERE S.ClassCode = C.Code FOR XML PATH('')) AS メンバー
FROM Classes AS C

値を [data()] として扱い、一旦スペースに変換してから、スペースを , に変換すると、スマートにな表示になる。
SELECT
 C.Code AS クラスコード
 ,C.Name AS クラス名
 ,REPLACE(
  (SELECT S.FirstName AS [data()] FROM Students AS S WHERE S.ClassCode = C.Code FOR XML PATH('')), ' ', ',') AS メンバー
FROM Classes AS C

[Android] 二段階認証をかけたアカウントを追加する。

Android 端末に Google アカウントを追加する際、対象アカウントに二段階認証を設定している場合は、通常のパスワードを入力しても認証が失敗する。二段階認証を設定しているアカウントを追加するには、「アプリ固有のパスワード」を設定する必要がある。
  1. Google のアカウント設定画面を開く。
  2. [2 段階認証プロセス] - [設定]
  3. [アプリケーション固有のパスワードの管理] を開く。
  4. 端末を選択し、アプリを選択(特に厳密である必要はない)したのちに「生成」ボタンを押下する。
  5. パスワードが表示されるので、表示されたパスワードを使用して端末でログインする。
なお、Android だけではなく、未登録の PC のメーラー、iPhone や iPad などで設定する場合にもこの方法でセットアップを行う。

[C#] ラムダ式での IN 句

ラムダ式で SQL の WHERE IN のようなことをするためには、検索の元となる値を配列にしてしまい、Contains を使用する。
そもそもデータを取得する時点で絞り込んでおくべきではあるが、こんな書き方もできるというメモ。
// 今さら DataTable ではあるが、使用されているケースは多い…はず?
var dt = new DataTable();
dt.Columns.Add("Class", typeof(int));
dt.Columns.Add("Name", typeof(string));
for (var i = 0; i <= 10; i++)
{   
    var dr = dt.NewRow();
    dr["Class"] = i;
    dr["Name"] = "Hoge " + i.ToString() + " 世";
    dt.Rows.Add(dr);
}
for (var i = 11; i <= 20; i++)
{
    var dr = dt.NewRow();
    dr["Class"] = i;
    dr["Name"] = "Gege " + i.ToString() + " 世";
    dt.Rows.Add(dr);
}
// 設定ファイルなどに記載された CSV を仮定。Class が 1 もしくは 3 であるレコードを取得する。
var settings = "1,3";
// string[] に分割後、List に変換。数値型にする。
var list = settings.Split(',').ToList().ConvertAll(x => int.Parse(x));
var ret = dt.AsEnumerable().Where(x => list.Contains((int)x["Class"]));
foreach(var x in ret)
{
    // 出力
    // Hoge 1 世
    // Hoge 3 世
    Console.WriteLine(x["Name"]);
}

[C#] 文字列の分割時に空白を無視

Split メソッドは色々と便利な使い方ができるが、何も指定しないと分割時に空白も含まれてしまう。これをオプション指定して空白を無視するには、若干書き方が変わってくる。
var s1 = "abc,def,,ghi,";            
var s2 = s1.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
// s2[0] = "abc"
// s2[1] = "def"
// s2[2] = "ghi"
StringSplitOptions 列挙体
http://msdn.microsoft.com/ja-jp/library/system.stringsplitoptions(v=vs.110).aspx

[Google Chrome] 指定したサイトを常にシークレットモードで開く

Incognito-Filter は、指定したサイト(アドレス)を開く際に自動的にシークレットモードで立ち上げてくれる拡張機能である。アドレスの指定は正規表現も使用できるので柔軟な設定が可能。

Incognito-Filter
https://chrome.google.com/webstore/detail/incognito-filter/cifilbmpnkjinlkchohdfcpdkmpngiik

[ASP.NET] テキストボックスにウォーターマークを表示させる

テキストボックスに対して、入力して欲しい値を予め薄く表示するウォーターマーク。実装方法は様々あるが、HTML5 対応ブラウザが対象であれば、以下のように placeholder タグを追加するだけで驚くほど簡単に実装できる。
なまえ:<asp:textbox id="TextBox1" placeholder="姓" runat="server"></asp:textbox>
 <asp:textbox id="TextBox2" placeholder="名" runat="server"></asp:textbox>

[jQuery] 複数の data をサーバー(ashx)に渡す

以下のように渡してしまうと、code1 しか渡すことができず、code2 を参照すると null 参照となってしまう。
$.ajax({
 type: "POST",
 url: "http://exsample.com/code.ashx",
 data: { "code1": $("#txtCode1").val() },
 data: { "code2": $("#txtCode2").val() },
 dataType: "json",
 cache: true,
 success: function (result) {
  hoge(result);
 },
 error: function (obj, err) {
 }
});
以下のように Json の変数に整形すると値を渡すことができる。
受け取り側は HttpContext の Request で取得する。
var dat = { "code1": $("#txtCode1").val(), "code2": $("#txtCode2").val() };
$.ajax({
 type: "POST",
 url: "http://exsample.com/code.ashx",
 data: dat,
 dataType: "json",
 cache: true,
 success: function (result) {
  hoge(result);
 },
 error: function (obj, err) {
 }
});

[C#] DataTable の Row に対して LINQ とラムダによる検索をする

DataTable を使用している業務システムは多いものだが、foreach で回しているケースも少なくない。.NET Framework のバージョンが古い場合はどうしようもないが、バージョンだけ上がっている場合は LINQ や ラムダを使用して高速に検索することができる。
var dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
for (var i = 0; i <= 10; i++)
{
 var dr = dt.NewRow();
    dr["Name"] = "hoge" + i.ToString();
    dt.Rows.Add(dr);
}

var ret = 0;

// Name の末尾が 0 であるレコードをカウントする(LINQ)。
ret = (from x in dt.AsEnumerable()
  where Convert.ToString(x["Name"]).EndsWith("0")
        select x).Count();
        Console.WriteLine(ret.ToString());

// Name の末尾が 0 であるレコードをカウントする(ラムダ)。
ret = dt.AsEnumerable().Count(x => Convert.ToString(x["Name"]).EndsWith("0"));
  Console.WriteLine(ret.ToString());

// 出力 : 2

[WinMerg] 行番号表示

デフォルト状態では行番号が表示されていないのだが、実はメニューから設定する。


[表示] - [行番号を表示 (N)]

[C#] DataRow の「アクセスできない保護レベル」

DataRow 型を初期化する際、つい以下のように記述しがちだが、エラーが出てしまう。


'System.Data.DataRow.DataRow(System.Data.DataRowBuilder)' はアクセスできない保護レベルになっています。

以下のように記述する。
// エラー
var dr1 = new DataRow();
// 初期化成功
var dr2 = new DataTable().NewRow();

[Explzh 64bit] サーバーに 7-ZIP64.DLL が見つかりません。


Explzh (64bit) のヘルプから「アーカイバ DLL の自動アップデート」を実行し、7-Zip の DLL しようとすると失敗する。サイトには以下のサイトより 64bit 版 7-zip64.dll をダウンロードして、システムフォルダに配置しろとの記述がある。

 綾川的趣味之接続集
http://homepage1.nifty.com/Ayakawa/ 

Windows 7 64bit 環境の場合、C:\Windows\SysWOW64 にコピーしろと書いてあるのだが( http://www.ponsoftware.com/archiver/help/X64DLL.htm )、実際にはなぜか C:\Windows\System32 に配置しないと動作しない……。

[PowerDVD] 引き続き、このコンテンツを再生するには、CyberLink PowerDVDをアップデートする必要があります

久しぶりに PowerDVD を使用としたら、以下のメッセージが出て再生できない。

引き続き、このコンテンツを再生するには、CyberLink PowerDVDをアップデートする必要があります。

この現象は、自動アップデートをかけても解消されず、手動でアップデートをかけるしかないようだ。アップデートファイルは、以下からダウンロードする。


アップデート・ユーザーガイドダウンロード - jp.cyberlink.com

途中で使用不可能になってしまうのはどうかと思う。

[C#] AD のオブジェクトを SID で検索する。

Active Directory のオブジェクトを DirectorySearcher を使って取り出す場合、SID (objectSid) を検索条件に指定するには以下のようにする。
複数の SID を指定する場合には若干書き方が変わる。
var directoryPath = "TEST-SV/OU=Hoge,DC=Hoo,DC=local";
var userName = @"Hoo\Administrator";
var password = "hogehoge";
using (var searcher = new DirectorySearcher(CreateDirectoryEntry(directoryPath, userName, password)))
{
    // 一つのみ指定する場合。
    searcher.Filter = ("(objectSid=S-9-9-99-999999999-9999999999-9999999999-1000)");
    // 複数指定する場合。
    searcher.Filter = ("(|(objectSid=S-9-9-99-999999999-9999999999-9999999999-1000)(objectSid=S-9-9-99-999999999-9999999999-9999999999-1001))");
    var result = searcher.FindAll();
    return result;
}

[ASP.NET MVC] FilePathResult で zip ファイルを返す際にエラーが発生する。

'/' アプリケーションでサーバー エラーが発生しました。

パス 'C:\temp\exportroot\Osg2-20033-Osg2sFileImporter-Batchlog_20140818132059430' へのアクセスが拒否されました。

説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。 

例外の詳細: System.UnauthorizedAccessException: パス 'C:\temp\' へのアクセスが拒否されました。 

ASP.NET は、要求されたリソースへのアクセスを許可されていません。ASP.NET の要求 ID に、リソースへのアクセス権を付与することを検討してください。アプリケーションが偽装していない場合、ASP.NET では基本プロセス ID (通常、IIS 5 では {コンピューター名}\ASPNET、IIS 6 および IIS 7 ではネットワーク サービス、IIS 7.5 では構成済みのアプリケーション プール ID) が使用されます。 を通じてアプリケーションが偽装している場合、ID は匿名ユーザー (通常は IUSR_MACHINENAME) または認証された要求元ユーザーになります。 

ASP.NET にファイルへのアクセスを許可するには、エクスプローラーでファイルを右クリックし、[プロパティ] を選択して、[セキュリティ] タブを選択します。[追加] をクリックして、適切なユーザーまたはグループを追加します。ASP.NET アカウントを強調表示し、希望するアクセスのボックスをチェックします。

エラーメッセージから、権限が足りないのかと思ったのだが、実は引数が間違えていた。fileName はフルパスを指定する。

// 上記のエラー
File("C:\temp", "application/zip", "file.zip");

// ダウンロード可能。
File("C:\temp\file.zip", "application/zip", "file.zip");
FilePathResult コンストラクター - msdn
http://msdn.microsoft.com/ja-jp/library/system.web.mvc.filepathresult.filepathresult(v=vs.118).aspx

[Visual Studio] Text Sharp でフォントを読みやすくする

Text Sharp
http://visualstudiogallery.msdn.microsoft.com/7aafa2ea-8c54-4da8-922e-d26bf018514d

Visual Studio に Clear Type 等を適用して、フォントを読みやすくするための拡張機能。ギザギザな文字が気に入らない場合に最適である。


拡張機能を入れると、Visual Studio のオプションの中に、 Text Sharp というメニューが追加される。
英語表記であるが、エディタの再起動なしに効果がすぐにわかるので、特に迷うことはないだろう。デフォルトではテキストビュー (Text views) とエディタ全体 (Main Window) に対して適用されるが、いずれかのみ適用させることもできる。

[Windows] 削除の確認メッセージを消す

Windows 8 以降の操作性で変わったところのひとつに、ファイルやフォルダの削除時に確認ダイアログが出なくなったことがある。はじめはやや違和感を感じたのだが、慣れると確認ダイアログはいらないと思うようになった。そして Windows 7 などを使うと、今度はダイアログが出ることが煩わしく感じるようになった。

確認ダイアログの表示・非表示は、ゴミ箱を右クリックして表示される設定ダイアログから簡単に変更できる。

[C#] PowerShell Office 365 への接続準備

Import-Module : モジュール ディレクトリに有効なモジュール ファイルが見つからなかったため、指定されたモジュール 'MSOnline' は読み込まれませんでした。
+ Import-Module <<<<  MSOnline
    + CategoryInfo          : ResourceUnavailable: (MSOnline:String) [Import-Module]、FileNotFoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

PowerShell から Office 365 へ接続する場合には、モジュールをインストールしておく必要がある。

Office 365 を管理または展開するための Windows PowerShell コマンドレット - TechNet
http://technet.microsoft.com/ja-jp/library/hh974317.aspx

インストールは、以下の順番で行う。
  1. IT プロフェッショナル 用 Microsoft Online Services サインイン アシスタント RTW
  2. Windows PowerShell 用 Azure Active Directory モジュール

インストールすると、PowerGUI のモジュールにも追加される。

[C#] 中央ディレクトリの終わりレコードが見つかりません。


エラーメッセージがややわかりづらいのだが、ZipFile クラスに zip アーカイブを読み込ませようとしたが、有効な zip ファイルでないか破損しているとこんなエラーが出る場合がある。
有効な zip アーカイブがどうかのチェックはなさそうなので、System.IO.InvalidDataException でキャッチするしかないようだ。

[C#・単体テスト] Shim を利用したアセンブリからの分離

単体テストメソッド作成時に Shim を利用するとメソッドのふるまいを変更したり、.NET アセンブリの呼び出しを変更したりできる。

shim を使用して単体テストでアプリケーションを他のアセンブリから分離する -msdn
http://msdn.microsoft.com/ja-jp/library/hh549176.aspx#AddFakes


サンプルを作成してみて気を付けなければならない(自分がはまった)のは、参照設定の System.dll を右クリックして 「Fakes アセンブリに追加」 を行うことだ。
Exception を判定したければ、catch をする必要があるのではないかと思う(私はテスト実装に慣れていないので他の方法があるかもしれないが)。
なお、shim はメソッドを書き換えるため、動作速度は遅くなる。

テスト対象クラス
namespace Sample
{
    public static class Y2KChecker
    {
        public static void Check()
        {
            if (DateTime.Now == new DateTime(2000, 1, 1))
                throw new ApplicationException("y2kbug!");
        }
    }
}
テストメソッド
[TestMethod]
public void Y2KChecker_発生する()
{
    using (ShimsContext.Create())
    {
System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(2000, 1, 1); };

try
{
    Y2KChecker.Check();
    Assert.Fail();
}
catch (ApplicationException)
{   
}
    }
}

[TestMethod]
public void Y2KChecker_発生しない()
{
   using (ShimsContext.Create())
   {
  System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(2001, 1, 1); };
  try
  {
     Y2KChecker.Check();
  }
  catch (ApplicationException ex)
  {
      Assert.Fail(ex.Message);
  }
  }
}

[VS2013] Private メソッドへの単体テスト実装

単体テストプロジェクトで Private メソッドへのテストを書きたい場合、方法はいくつかあるようだが、外部からアクセスできる public メソッドを書いてしまうのが手っ取り早い。
  1. クラスそのものは public である必要がある。
  2. #if DEBUG を書いておけば、デバッグ時のみ有効化される。

テスト対象クラス
using System;

namespace Sample
{
    public static class Program
    {
        static void Main(string[] args)
        {
        }
#if DEBUG
        public static string UtGetCodeName(string name) { return GetCodeName(name); }
#endif
        static string GetCodeName(string name)
        {
            if (name.Length == 0)
            {
                return null;
            }
            var r = new Random();
            return "C" + r.Next(10, 99).ToString() + name.Substring(3);
        }
    }
}
テストメソッド
[TestMethod]
public void GetCodeName_nullではないこと()
{
    Assert.IsNotNull(Sample.Program.UtGetCodeName("Daniel"));    
}
[TestMethod]
public void GetCodeName_nullになること()
{
    Assert.IsNull(Sample.Program.UtGetCodeName(""));
}

[C#] イベントログをラムダ式で検索

イベントログを抽出したい場合、foreach ですべて列挙すると時間がかかってしまう。
これをラムダ式で検索したい場合は、以下のように行う。
// 一週間のうち、ソースが SecurityCenter であるイベントログを取得。
// 戻り値は IEnumerable となる。
var period = DateTime.Now.AddDays(-7);
var logName = "Application";
var machineName = ".";
if (EventLog.Exists(logName, machineName))
{
    var log = new EventLog(logName, machineName);
    var ret = log.Entries.Cast().Where(m => m.TimeGenerated >= period && m.Source == "SecurityCenter");
    log.Close();
}
なお、TimeGenerated には少々癖があり、必ずしもイベントログに書込まれた時間ではないらしい。

EventLogEntry.TimeGenerated プロパティ - msdn
http://msdn.microsoft.com/ja-jp/library/system.diagnostics.eventlogentry.timegenerated%28v=vs.110%29.aspx

[C#] フォルダ内でパターンに一致しないファイルを削除

C# におけるフォルダ内ファイルの列挙は GetFiles() メソッドが用意されていたが、これは探索に時間がかかってしまう場合があり効率が悪いものであった。
そこで .NET Framework 4 からは EnumerateFiles() メソッドが追加された。

ファイルやディレクトリの一覧を効率的に取得するには?[4以降、C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/1018enumfiles/enumfiles.html

パターンに一致するファイルはこれですぐに探せるのだが、例えば、パターンに一致しないファイルを消したい場合はもう一工夫する。
以下は D:\test 以下にある、本日日付以外のファイルをすべて削除する場合のサンプル。
var today = DateTime.Now.ToString("yyyy-MM-dd");
// .txt ファイルのみ削除対象にする場合は、EnumerateFiles の第二引数にパターンをセットする。
// foreach (var path in Directory.EnumerateFiles(@"D:\test", "*.txt").Where(x => !x.Contains(today)))
foreach (var path in Directory.EnumerateFiles(@"D:\test").Where(x => !x.Contains(today)))
{
   var fileInfo = new FileInfo(path);
   fileInfo.Delete();
}
Directory.EnumerateFiles メソッド - msdn
http://msdn.microsoft.com/ja-jp/library/vstudio/system.io.directory.enumeratefiles%28v=vs.100%29.aspx

[Windows8.1] ライブラリの表示

Windows 8.1 のエクスプローラ-の初期設定では、ライブラリが表示されていないため、表示させたい場合は以下の手順を行う。
  1. [ 表示 ] メニューの [ ナビゲーションウィンドウ ] をクリックする。
  2. [ ライブラリの表示 ] をクリック。

[コマンドプロンプト] 貼り付けのショートカットキー

コマンドプロンプトで、貼り付けをキーボードから行いたい場合は、以下の通りである。
  1. 「Alt + Space」でメニュー画面を出す。
  2. 編集 (E)
  3. 貼り付け (P)
ちなみに、コピーも「Ctrl + C」ではなく、Enter キーで行う。

[C#, VB.NET] 配列文字列を区切り文字を使って連結

String.Join メソッドは、配列の要素を指定した区切り文字で連結する。

String.Join メソッド - msdn
http://msdn.microsoft.com/ja-jp/library/system.string.join%28v=vs.110%29.aspx

var dat = new string[] { "Michael", "Christopher", "Joshua", "Matthew", "Daniel" };
var ret = String.Join(",", dat);
// Michael,Christopher,Joshua,Matthew,Daniel
Console.WriteLine(ret);

var dat2 = new List() { "Robert", "James", "Nicholas" };
var ret2 = String.Join(",", dat2);
// Robert,James,Nicholas
Console.WriteLine(ret2);
VB.NET の場合も同等の動きをするのだが、Join 関数は VB にしかない。
C# と比較するとなかなか興味深い動作である。
Dim data As String() = {"Michael", "Christopher", "Joshua", "Matthew", "Daniel"}
Dim result = String.Join(",", data)
' Michael,Christopher,Joshua,Matthew,Daniel
Console.WriteLine(result)

' Join 関数は区切り文字を省略できる。
Dim result2 = Join(data)
' Michael Christopher Joshua Matthew Daniel
Console.WriteLine(result2)

' Join 関数で区切り文字を指定する場合は、第二引数に指定する。
Dim result3 = Join(data, ",")
' Michael,Christopher,Joshua,Matthew,Daniel
Console.WriteLine(result3)
Join 関数 (Visual Basic) - msdn
http://msdn.microsoft.com/ja-jp/library/b65z3h4h%28v=vs.90%29.aspx

[C#] イベントログへの書き込み(Windows Vista, 7...以降)。


イベントログへの書き込みについては、以下のようなサンプルをよく見かける。
ソースの存在チェックを行ってから、イベントログへ書き込みを行う処理だ。
var source = "EventLogTest";
var logname = "Application";
var message = "イベントログに書込むテスト。";
var eventId = 9999;
var category = (short)100;
var rowData = System.Text.Encoding.Unicode.GetBytes("ABCDEFGH");

if (!System.Diagnostics.EventLog.SourceExists(source))
{
 var eventSourceData = new EventSourceCreationData(source, logname);
        EventLog.CreateEventSource(eventSourceData);
}
EventLog.WriteEntry(source, message, System.Diagnostics.EventLogEntryType.Error, eventId, category, rowData);
しかし、Windows Vista 以降ではユーザーアカウント制御 (UAC) により、イベントソースへの問い合わせを行った時点で例外が発生する。

型 'System.Security.SecurityException' のハンドルされていない例外が System.dll で発生しました
追加情報:ソースが見つかりませんでしたが、いくつかまたはすべてのログを検索できませんでした。アクセス不可能なログ: Security

Visual Studio を管理者権限で実行するか、他の方法であらかじめソースの登録を行っておくしかない。

[C#] 正規表現で角括弧 [ ] の中身を取得

角括弧 [] は .Net Framework ではメタ文字として扱われるため、それ自体を対象にしたい場合はバックスラッシュ(\)でエスケープをしなければならない。

.NET Frameworkがサポートする正規表現クラスを徹底活用する ― (3/4) - @IT
http://www.atmarkit.co.jp/ait/articles/0304/12/news002_3.html

確実に角括弧の中に含まれている文字列を取得したい場合は以下のようにする。
var input = "テスト[[[あいうえお[Code=9999]テストテスト[Code=]]]";
var regex = new Regex(@"\[Code=(?.*?)\]");            
var match = regex.Match(input);
var result = match.Groups["value"].Value;
Console.WriteLine(result);

// Regex の定義が重要。クエッションマークの有無で結果がかなり異なってくる。

// @"\[Code=(?.*?)\]"
// 結果 : 9999

// @"\[Code=(?.*)\]"
// 結果 : 9999]テストテスト[Code=]]

[Google マップ] 元のバージョンに戻せる

Google マップは、以前のバージョンに戻すことができる。
画面右下の 「?」 マークをクリックすると、「以前のマップに戻る」 というメニューがある。
新しい Google マップ についての意見を聞かれる。チェックを入れなくても良いが、戻す場合は 「以前の Google マップに戻る」 リンクをクリックする。
旧バージョンのマップに戻る。今度も旧バージョンを使用するかどうか聞かれるので選択する。

個人的には、新しいマップはとにかく動作が重くなり、ストリートビューが使いづらくなった印象だった。この手順で旧バージョンの Google マップを使えるのだが、正直いつまでこれが通用するか不明である。

[C#] AD の ObjectGUID を文字列変換。

Active Directory (AD) のオブジェクトを System.DirectoryServices.DirectoryEntry を使用して取得する際、objectGUID は byte 型で返却される。
これを文字列にしたい場合、Guid オブジェクトの ToString メソッドで変換するのだが、引数により取得できる文字列が異なる。
// かっこあり : ToString("B") でも可。
// {1bac5384-da6d-46c9-9b41-c8894cd7b159}
var guid1 = new Guid((byte[])directoryEntry.Properties["objectGUID"][0])

// ハイフンあり(デフォルト)。
// 1bac5384-da6d-46c9-9b41-c8894cd7b159
var guid2 = new Guid((byte[])directoryEntry.Properties["objectGUID"][0]).ToString("D")

// ハイフンなし。
// 1bac5384da6d46c99b41c8894cd7b159
var guid3 = new Guid((byte[])directoryEntry.Properties["objectGUID"][0]).ToString("D")

// 丸かっこあり。
// (1bac5384-da6d-46c9-9b41-c8894cd7b159)
var guid4 = new Guid((byte[])directoryEntry.Properties["objectGUID"][0]).ToString("D")

[C#] コマンドプロンプトの窓を非表示にする


アプリケーションの中で、Process.Start メソッドを使用して他のコンソール・アプリケーションの EXE を起動させるとき、しばしば「黒い窓」を出したくないという要望がある。
そういう場合には ProcessStartInfo クラスのプロパティを設定するとよい。
var startInfo = new ProcessStartInfo();
startInfo.FileName = @".\Test2.exe";
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;

// さらに処理終了まで同期して待つ場合
var process = Process.Start(startInfo);
process.WaitForExit();
コマンド・プロンプトを表示せずにコンソール・アプリケーションを実行するには?[C#、VB]- @IT
http://www.atmarkit.co.jp/fdotnet/dotnettips/654nowinexec/nowinexec.html


なお、窓を完全に非表示にしたい場合は、プロジェクトのプロパティから、アプリケーションの種類を「Windows フォーム アプリケーション」に変更する。
この設定を行うと、まったくウィンドが出ずに処理が開始される。

コマンド・プロンプトを表示しないコンソール・アプリケーションを作成するには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/837nodisplayconsole/nodisplayconsole.html

[PowerShell] try catch finally によるエラー処理

PowerShell 2.0 以降は、try-catch が使用できる。
try
{
        $x = 1 / 0
}
catch [Exception]
{
        $retMessage = $_.Exception.Message
        #Write-Host $retMessage
        # 0 で除算しようとしました。
}
finally
{  
}

[PowerShell] 処理のウェイト

デバッグなどを行うため、PowerShell の処理を一時停止したい場合は以下のコマンドレットをかませる。
デバッグなどを行うため、PowerShell の処理を一時停止したい場合は以下のコマンドレットをかませる。
# 5 秒ウェイト
Start-Sleep -s 5
# ミリ秒の指定
Start-Sleep -m 10000

[Visual Studio] コマンドライン引数(デバッグ)

バッチプログラム等で、デバッグ時にコマンドライン引数を与えたい場合は、[プロジェクトのプロパティ] - [デバッグ] 画面にある、開始オプション・コマンドライン引数に値を入力する。なお、複数のコマンドライン引数を与えたいときは、半角スペースでそれぞれ区切る。

[PowerShell] Get-Date による日付フォーマットいろいろ

Get-Date コマンドは、現在日付を取得することができるのだが、-Format 引数を与えることでフォーマットを変更することができる。なお、大文字と小文字で挙動が異なるので気を付けなければならない。
# 2014年4月1日
Get-Date -Format D
# 2014/04/04
Get-Date -Format d
# 2014/04/01 00:00:00
Get-Date -Format G
# 2014/04/01 00:00
Get-Date -Format g

# 20140401
Get-Date -Format "yyyyMMdd"
なお、以上のほかにも様々な引数がある。

 標準の日付と時刻の書式指定文字列 - msdn
http://msdn.microsoft.com/ja-jp/library/vstudio/az4se3k1.aspx

[PowerShell] メールアドレスの @ 前を取得

PowerShell で正規表現を使用して、メールアドレスの @ 前を取得する場合は、以下のようにする。
$txt = 'abcdef1200@company.com'
$re = "[a-z0-9!#\$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+/=?^_`{|}~-]+)*@"
$s = [regex]::Match($txt, $re, "IgnoreCase").Value.Replace("@","")

# abcdef1200
Write-Host $s

[Word] 作業ファイルを作成できません。環境変数 TEMP の設定を確認してください。

Word を起動する度にこのようなメッセージが出るときがある。この理由は様々あるが、なんらかの理由で環境変数にあるパスへアクセスできなくなっていることもある。
レジストリに記載されているパスは以下の通り。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Cache

パスに関してはアクセスできるものであれば何でも良い。

[C#] DataTable への主キー設定と確認

DataTable には通常のテーブル同様、主キー (PrimaryKey) が設定できる。
var dt = new DataTable();
dt.Columns.Add("Key", typeof(int));
dt.Columns.Add("Name", typeof(int));
// 主キー設定
dt.PrimaryKey = new DataColumn[] { dt.Columns["Key"] };
// 主キーの取得。DataColumn[] として返却される。
var columns = dt.PrimaryKey;
VB での書き方など、詳細ははこちらで確認できる。 DataTable.PrimaryKey プロパティ - msdn

[C#] TryParse での日付 (yyyymmdd) チェック

TryParse メソッドを使用した日付チェックでは、元の文字列に注意を払わなければならない。
string s = "20140101";
DateTime d1, d2;
bool res1 = DateTime.TryParse(s, out d1);
bool res2 = DateTime.TryParseExact(s, "yyyymmdd", null, DateTimeStyles.None, out d2);

// False
Debug.WriteLine(res1.ToString());
// True
Debug.WriteLine(res2.ToString());
DateTime.TryParse では、以下のようなパターンの文字列であれば日付として許容される。
"2014.01.01"
"2014-01-01"
"2014/01/01"
"2014年01月01日"

しかし、データでよくありがちな "yyyymmdd" は許容されずに弾かれてしまう。
この場合、文字列を分解して上記のような形式に直すのもいいが、DateTime.TryParseExact でパターンを指定することでチェックが行える。DateTimeStyles 列挙体が必須になるが、特に指定がなければ DateTimeStyles.None としておく。

DateTime.TryParse メソッド
http://msdn.microsoft.com/ja-jp/library/ch92fbc1(v=vs.110).aspx

DateTime.TryParseExact メソッド
http://msdn.microsoft.com/ja-jp/library/system.datetime.tryparseexact(v=vs.110).aspx

DateTimeStyles 列挙体
http://msdn.microsoft.com/ja-jp/library/91hfhz89(v=vs.110).aspx

[C#] Enum の文字列を取得

Enum は数値で扱うのが、その項目自体を文字列で取得したいケースもある。
foreach で列挙すると、以下のようになる。
using System.Diagnostics;
enum Size
{
    S,
    M,
    L,
    すーぱーさいず,
}
foreach (string x in Enum.GetNames(typeof(Size)))
{
    // 出力結果
    // S
    // M
    // L
    // すーぱーさいず
    Debug.WriteLine(x.ToString());
}
Enum.GetNames メソッド
http://msdn.microsoft.com/ja-jp/library/system.enum.getnames(v=vs.110).aspx

Enum については、こちらでも色々と書いている。

[C#] Array.FindAll による要素の複数結果検索

C#2.0 でも、delegate と Array やリストコレクションが持つメソッドを組み合わせると、リファクタリング可能なコードを書くことができる。
以下は、Array.FindAll を使用して、CSV の値から文字列の操作を行っている。
using System;
using System.Collections.Generic;
using System.Diagnostics;

string[] csv = { "abc,def,aab,dee,cba,bac" };
string[] ret = Array.FindAll(csv, delegate(string x)
{
    // a が含まれる文字列を検索する(あいまい検索)。
    return x.Contains("a");
});

// 結果 : abc, aab, cba, bac
Debug.WriteLine(ret);

string[] ret2 = Array.FindAll(csv, delegate(string x)
{
    // a から始まる文字列を検索する(前方一致検索)。
    return x.StartsWith("a");
});

// 結果 : abc, aab
Debug.WriteLine(ret2);
ret 行はリファクタリング可能。

Array.Find ジェネリック メソッド - msdn
http://msdn.microsoft.com/ja-jp/library/d9hy2xwa(v=vs.80).aspx

[C#] ContextSwitchDeadlock の例外

マネージ デバッグ アシスタント 'ContextSwitchDeadlock' では '' に問題を検出しました。
追加情報: CLR は、COM コンテキスト 0x352be0 から COM コンテキスト 0x352a70 へ 60 秒で移行できませんでした。ターゲット コンテキストおよびアパートメントを所有するスレッドが、ポンプしない待機を行っているか、Windows のメッセージを表示しないで非常に長い実行操作を処理しているかのどちらかです。この状態は通常、パフォーマンスを低下させたり、アプリケーションが応答していない状態および増え続けるメモリ使用を導く可能性があります。この問題を回避するには、すべての Single Thread Apartment (STA) のスレッドが、CoWaitForMultipleHandles のようなポンプする待機プリミティブを使用するか、長い実行操作中に定期的にメッセージをポンプしなければなりません。

長いメッセージだ。
Windows Form で長い処理を行っている間に、このようなメッセージが表示されることがある。
メッセージを出なくさせるには、ContextSwitchDeadlock の例外が出ても中断させないように設定すればよい (問題が解決したわけではないので、なんらかの対処は必要だろうが……)。

  1. デバッグ -> 例外 (Ctrl + D, E)
  2. Managed Debugging Assistants, ContextSwitchDeadlock のチェックをオフにする。

[Chrome33] User StyleSheets と、新しいタブの改悪が確定?


Chrome は勝手にアップデートされるので、ある日突然仕様変更が行われている。
そして、今回のアップデートで Custom.css が効かなくなったようだ。

これは Chrome で強制的にスタイルシートを適用させて、すべてのウェブサイトを好みのフォントで表示させるものだったのだが……。これがなくなるとフォントレンダリングのクソな Windows では痛い。

そもそも、設定ページから行えるフォント設定を行ってもあまり意味がないからこの機能を重宝していたのだが、これでは自由がなさ過ぎる。
厄介なことに、あるページやテキストボックスの一部によっては、その設定のフォントで表示されていたりするので、意味がわからない。

漢字のない英語圏の人間にはこういう機能がどれほど重要なのか理解できないのだろう。


さらに、今回のアップデートでは、新しくタブを開いた際、「よく開くタブの一覧」 が表示されるようになった。これは少し前のアップデートで無効にできたのだが、これが見事に強制的に戻り、しかも無効にできなくなった。

Chromeの「おせっかい」な新しい新規タブページを以前の設定に戻す方法
http://www.lifehacker.jp/2013/10/131004chrome.html

Chrome ひどい。