findの結果をxargsで渡してchown とか chmod
普通にパイプで繋ぐだけでは、ファイル名に空白とかがある場合うまくいかない。
というわけで、こうしてやる。
$ find ./ -type d -print0 | xargs -0 chmod 755
約10年ぶりの更新
pass忘れ等により、長いこと放置状態でしたが、先日奇跡的にログインに成功!
もはやお仕事で直接コードを書くことはなく、"管理ときどき技術"な立ち位置な日々でゴザイマス。
今は技術系のちょっとしたメモもののサイトがごろごろ充実しているから、
もはや存在意義が自分専用でしかないかもしれませんが、最近の備忘録。
Windowsのテーマ変更を知る
現在のテーマの調べ方
現在のテーマが何に設定されているかどうかは以下のレジストリを確認すればOK。
レジストリパスはWindows XPの場合も Vistaの場合も同じ。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ThemeManager]
- ColorNameが存在しない(ThemaActive? = 0でも同じ)
- ColorNameが存在する
ここらへんは参考コードがCode Projectに載ってたりする。
http://www.codeproject.com/KB/cs/xptheme.aspx
テーマ変更検出
ウィンドウメッセージ「WM_WININICHANGE」を拾うことで検出可能。
WININICHANGEは、ウィンドウズの設定変更時に色々飛んでくるので注意。
WININICHANGEを拾って、現在のテーマを調べ、変更があるかどうかを判定すればよさそう。
というわけで、以下がサンプルコード。
protected override void WndProc(ref Message m) {
const int WM_WININICHANGE = 0x001A;
base.WndProc(ref m);
if (m.Msg == WM_WININICHANGE) {
Console.WriteLine(m.LParam.ToString() + "\tTheme : " + getCurrentTheme());
}
}public Theme getCurrentTheme() {
Theme currentTheme = Theme.Classic;
String regPath = @"Software\Microsoft\Windows\CurrentVersion\ThemeManager";
Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath);
if (regkey != null) {
if ((string)regkey.GetValue("ThemeActive") == "1") {
String colorName = (string)regkey.GetValue("ColorName");
if (colorName.Equals("NormalColor")) {
return Theme.Default;
} else if (colorName.Equals("HomeStead")) {
return Theme.XP_Green;
} else if (colorName.Equals("Metallic")) {
return Theme.XP_Silver;
} else {
return Theme.Unknown;
}
}
}
return currentTheme;
}public enum Theme {
Classic,
Default,
XP_Green,
XP_Silver,
Unknown
}
実行例は以下のとおり(Windows Vista上で、デフォルトからクラシックに変更した場合)
0 Theme : Default
0 Theme : Classic
3076484 Theme : Classic
3076484 Theme : Classic
3076484 Theme : Classic
3076488 Theme : Classic
3076484 Theme : Classic
3076476 Theme : Classic
3076488 Theme : Classic
3076476 Theme : Classic
3076464 Theme : Classic
Windowsのテーマ変更を検出する
仕事納めの日が、午後出張で直帰(そのまま忘年会へ…)だったので、細々とした事が残ってたままに。
別に年明けからでも大丈夫なんだけど、なんとなく気分が悪いので、年の瀬休日出社して片付けることに。
XMLシリアライズ時のInvalidOperationException
オブジェクトをシリアライズする際には,引数なしのコンストラクタが必要.(コンストラクタを一つも定義していなければデフォルトコンストラクタ(引数なし)がoverrideされるから問題ない).
もし,引数ありのコンストラクタのみを定義し,引数なしのコンストラクタを定義していない場合,シリアライズ時にInvalidOperationExceptionが発生する。
このInvalidOperationException,コンストラクタに問題があるオブジェクトが親か子かでメッセージの文面が異なってくるからいやらしい.
例えば前記事の例だと,Companyオブジェクトに引数なしコンストラクタが存在しない場合は
System.InvalidOperationException はハンドルされませんでした。
Message="Sample.Company にはパラメータを持たないコンストラクタが含まれていないため、これをシリアル化することはできません。"
ところが,Companyオブジェクトには問題なくて,Personオブジェクトに引数なしコンストラクタが存在しない場合は
System.InvalidOperationException はハンドルされませんでした。
Message="型 'Sample.Company' を反映中にエラーが発生しました。"
となり手がかりが少なくなる.
配列のシリアライズで、配列そのものにタグを与えたくない
System.Xml.Serialization.XmlSerializer を使用してプロパティに配列を持つオブジェクトを普通にXMLシリアライズする
と、配列にタグがついて、さらに配列の要素一つ一つにもタグがつく.
たとえば,
class Person {
int id;
String name;// ... setter, getterは省略 ...
}class Company {
Person[] persons;
String companyName;public String CompanyName {
get { return this.companyName; }
set { this.companyName = value; }
}
public Person[] Persons {
get { return this.persons; }
set { this.persons = value; }
}
}
をシリアライズすると
1001
Taro
1002
Jiro
・・・
となり,Personsタグが余計な感じとなる.
この場合,CompanyクラスのPersonsプロパティに [XmlElement(Type = typeof(クラス名))]という定義を付けると,Personsタグを省略し,Personタグの繰り返しだけにすることができる.
例:
[XmlElement(Type = typeof(Person))]
public Person[] Person {
get { return this.persons }
set { this.persons = value }
}
1001
Taro
1002
Jiro
・・・