仮面's profile宇宙仮面の C# 研究室.Live SpacePhotosBlogListsMore ![]() | Help |
|
|
July 16 プロセスモニタどこかで見たことのあるようなものをWPFで作ってみた。 簡単に作れるだろうと思っていたのだけど、いくつか、ハマり中。 1.プロセスの情報を取るいいI/Fが見つからない。System.Diagnostics.Process.GetProcesses() だと、プロセッサタイムが取得できないので、しかたなしにWMIでプロセスの情報を取っているのだけれど、結構重くって、CPUパワーが食われまくり。パフォーマンスカウンターを全プロセス分持つのも芸がないし、Win32 SDKを叩くか?? .NETで、いい方法ない? 2.画面のリサイズもフォントサイズとPolygon の関係をちゃんと考えないといけないので、意外と難しい。 3.おまけに6角形にレイアウトするのも面倒。誰か、HexaFlowコントロール作ってくれないかな w でも、こんな感じで http://uchukamen.com/pmon/publish.htm 意外と見ていて面白い。 PS. LINQ は偉大だ。もう LINQ 無しでは生きていけない体になってしまった。 July 15 Generic Dictionary の foreachあまり使わないので忘れないようにメモ Dictionary<uint, Process> processDict = new Dictionary<uint, Process>(100); foreach (KeyValuePair<uint, Process> val in processDiff) July 13 WPF ユーザーコントロール<UserControl x:Class="WpfApplication6.Cell" <Label Name="label1" HorizontalContentAlignment="Center" Margin="6,15,6,0">Label</Label> </UserControl> 用途は・・・ Process 情報の取得に関するメモ2WMI を使用して Process 情報を取得する際に LINQ を使用しようとすると ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process"); var query = from proc in queryCollection1 select proc; エラー 1 ソース型 'System.Management.ManagementObjectCollection' のクエリ パターンの実装が見つかりませんでした。'Select' が見つかりません。範囲変数 'proc' の型を明示的に指定してください。 C:\Users\uchukamen\Documents\Visual Studio 2008\Projects\WpfApplication6\WpfApplication6\Window1.xaml.cs 140 38 WpfApplication6 というエラーになる。 回避方法は、範囲変数 proc の型を明示的に指定するために、queryCollection1.Cast<ManagementObject>() としてあげるとうまくいった。うむむむむ・・・ ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process"); var query = from proc in queryCollection1.Cast<ManagementObject>() select proc; ------ もうちょっと見やすく?すると、IEnumerable<ManagementObject> にキャストしてくれるということ。 ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process"); var procs = from proc in procQuery select proc; foreach (var process in procs) Process 情報の取得に関するメモVisual Studio 2008 , Vista で、GetProcesses() でプロセス情報を取得する際に、TotalProcessorTime などプロセッサタイムを取得しようとすると、Win32Exception により取得できない。なぜ?? var query = from proc in System.Diagnostics.Process.GetProcesses() foreach (var process in query) ----------------- WMI を使用すれば、取得可能。 ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process"); foreach (ManagementObject mo in queryCollection1) Visual Studio 2010 Parallel - Processシーケンシャルだと var query = from proc in System.Diagnostics.Process.GetProcesses() select proc; これがパラレルだと、 var query = from proc in System.Diagnostics.Process.GetProcesses() select proc; 処理的には、パラレルでもシーケンシャルでも関係ないので、パラレルで実行しているほうが処理する人の感覚(意図)に近いのかもしれない。 Visual Studio 2010 ParallelVisual Studio 2010 beta を入れてみた。
using System.Threading; … Stopwatch sw = new Stopwatch(); … 実行結果 x : ManagedThreadId ------------- 0 : 8 こんなことができてしまうなんて・・・ May 25 Codeseek 勉強会のWinRing0の資料をアップしました。第40回codeseek勉強会 「宇宙仮面のWinRing0」 (共催:tk-engineering、こみゅぷらす、eパウダ~、.Net/C# Group) 開催日:2009年5月19日(火) 19:00~21:00 18:55に6F受付集合 場所:マイクロソフト社新宿オフィス6F会議室 募集締め切り:2009年5月16(土)23時59分59秒 20名まで 参加費無料 May 05 CPUの温度取得に関するメモ4Intel® 64 and IA-32 Architectures Software Developer’s Manual によると、今使用中の ASUS P5LD2-V + Pentium 4 D では、MSR から CPU の温度が取れないことが判明した。 で、http://kariunten.homeip.net/programming/winring0.html にマザーボードのI/Oコントローラからデータを取得する方法が載っていたので、OpenLibSys で試してみた。 ASUS P5LD2-Vのマニュアルを調べてみると、コントローラは W83627EHF だったので、そのマニュアル http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_W83627EHG.pdf を調べてみた。それによると、このチップには温度センサーが3つ搭載されている。ただし、マザーボード上で使用されているのは、CPUTIN Temperature、SYSTIN Temperature の2つのみで、AUXTIN Temperatureは使用されていない模様。 このコントローラーからデータを取得するには、IO ポートからデータを取得すればよい。 取得する方法は、0x295 ポートにレジスタを指定、0x296 ポートからデータを取得するという手順。 ただし、バンクが 0, 1, 2, 3, 4 とあり、0x50 以上のレジスターにアクセスするには、バンクを切り替える必要がある。バンクの切り替え方法は、0x4E ポートの下位3ビットで指定する。 CPUTIN (CPUの温度)は、 バンク1、0x50 レジスタにハイビット(温度 ℃) バンク1、0x51 レジスタにロービット(温度 7ビット目が立っていれば +0.5℃) となっているので、次のようなコードになる。 //======================================= // バンク1 Console.WriteLine("CPUTIN Temperature Low : ...." + lo.ToString("X") + "\r\n"); float CPUTIN = hi + ((lo & 0x80) != 0 ? 0.5f : 0); Console.WriteLine("CPUTIN Temperature: ...." + CPUTIN.ToString() + "\r\n"); 同様に、SYSTIN (マザーボードの温度)は、バンク0、0x27 レジスタなので、 //======================================= // バンク0 を指定 Console.WriteLine ("SYSTIN Temperature: ...." + hi.ToString() + "\r\n"); なお、SYSTINでは、0.5℃単位の測定はできない仕様になっている。 結果は次の通り。 [CPUTIN Temperature] [SYSTIN Temperature] 下は、ASUS のおまけアプリの Probe II のデータ おおおおっ、ちゃんと取れるじゃないですか。OpenLibSys 偉大だ。 というか、Core2にアップしてしまえば、MSRで取れるので、こんなことしないですむんだけどなぁ・・・ というか、こんなハード固有の実装させないように頑張ってよ >> MS というか、温度を気にしないといけないような CPU 勘弁してよ >> Intel, AMD CPUの温度取得に関するメモ3MSR(Model Specific Register) 0x19C Bits [22:16] で温度が取得できることは確認できたが、このセンサーの値は、Tjmax への相対値であることがマニュアルに書かれている。しかし、そのTjmaxの値をMSRから取得する方法がマニュアルに書かれていない。 いろいろ探していたらば、 http://software.intel.com/en-us/forums/deleted-posts/topic/51574/page/1/ で、MSR 0xEE で取得が可能なようだが、undocumented だそうだ。ちょっと古い資料なので、85度か100度と書かれている。 http://www.xtremesystems.org/forums/showthread.php?t=179044&page=23 によると、0xEE の bit:30 で、0=100 1=85 といううわさもある。 一方、Q6600 では、95度らしいという書き込みもある。 http://www.xtremesystems.org/forums/showthread.php?t=179044&page=27 Atom の場合、20度室温で 0x19C Bits [22:16] から88前後が返されているので、100度にしても合わない。 http://download.intel.com/design/processor/datashts/320032.pdf によると、a catastrophic processor temperature of 125°C (maximum), or if the THERMTRIP# MSR 0xEE で取得してみると、 000000EE: 00000000 02F90002 となり、仕様が分からない。 http://www.bugtrack.almico.com/view.php?id=1150 によると、 if bit 30 of MSR(0x00EE) is 1 then こんな情報もある。 それにしても、xtremesystems.org のスレッドがものすごいことになっているのには、驚いた。 いずれにしても、インテルが仕様をはっきり書いていない(NDAを結ばないともらえないらしい)のが悪いということがよくわかった。 May 04 CPUの温度取得に関するメモ2石坂さん、渋木さんに教えていただいたサイドバーガジェットを Windows 7 Beta on Atom N280で動かしてみました。こんな感じ。 原理はデバイスドライバーで、Ring0のカーネルモードに移行して、そこでアセンブラでRDMSRにより、Model Specific Register を叩いて、直接モードスペシフィックレジスターからデータを読み取っていますね。そのためのライブラリがOpenLibSysから提供されている。なるほど、それなら早いはずだ。それにしても、OpenLibSysを作った人は偉いなぁ・・・とひとしきり感動しました。 なお、Vista on Pentium4 Dでは、温度が取得できない。orz。MSR的には、0x19C の 22:16 で同じ仕様に見えるんだけど、どこか細かいところで違うのかな・・・ なお、MSRは、文字通りモデル固有のレジスタであるため、プロセッサのモデルごとに仕様が異なっている。Intel のIntel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3Bによると、Core2、Atom、P4 and Xeon、Core Solor and Core Duo、Pentium M、P6、Pentiumとファミリーごとに説明が分かれています。 April 29 CPU 温度の取得に関するメモだんだんと暑い季節になってきて、Core2ではない Pentium 4 Dにとっては、辛い季節になってきました。室温が上がると、調子が悪くなるので、まじめに深刻な問題です。そこで、先日ケースにファンを増設したら、だいぶ効果があるようで、35度ぐらいでおちついていますが、CPUの温度のモニタリングしたいと思って、ちょっと調べてみました。 WMI の “Win32_TemperatureProbe” が一番まともな方法のようだが、現在のPC “ASUS P5LD2-V”, eee PC 1000 HE では、このインターフェースがサポートされていない模様。 いろいろ調べてみると、MSAcpi_ThermalZoneTemperature を使った記事がいくつかある が、そもそもそんな I/F の情報は MSDNに載っていない。もう使われていないということか? さらに調べてみると、 http://kariunten.homeip.net/programming/winring0.html にマザーボードのコントローラを直接操作する方法が載っていた。そうきますか~~~w。 と思って、そのコードを見てみると、 で、Windowsからハードウェア(I/O port, MSR, PCI bus, and etc...)へのアクセスを可能とする WinRing0 が提供されているコードを利用している。 さらに、そこから http://www.techpowerup.com/realtemp/ で、all Intel single Core, Dual Core, Quad Core and Core i7、さらにはNvidia のGPUの温度まで取得できるプロジェクトを発見。 試してみたが、Pentium 4 Dは、サポートされていない;; eee PC 1000 HE の Atom N280だと? 1℃ ! すばらしい CPUだ w ASUS からProbe II というモニターツールがあるから問題ないんだけどね。 温度、ファン回転数ぐらい WMI でちゃんと取れるようにしてよね。>> MS それより、せめてCore2にしろよという突っ込みは却下。 March 14 Visual Studio 2008 の修復インストール、アンインストールができないVisual Studio 2008の調子が悪く、ASP.NETの開発ができなくなってしまった。特に何もしていないのに突然の症状。原因不明。しかたないので、修復セットアップしようとしたら、セットアップもできなくなっている。 アンインストールもできない。困ったと思っていたら、 もりさんのページで、 Visual Studio 2008 自動アンインストールツールが公開されています。 が紹介されていた。 Visual Studio 2008 をアンインストールするhttp://msdn.microsoft.com/ja-jp/vstudio/bb968856.aspx 無事安易ストール完了。 さて、インストールしますか。 ・・・1時間後、インストール無事終了。起動してみると、ブルースクリーンでVista 落ちた。 再起動後、WebApplication を作ってみただけで、 ということで、なんかすごくおかしくなっている。 WinForm は問題なくプロジェクトの作成、実行ができる。 IISがらみか? February 03 RDF を LINQ で読むstring gooRankingUrl = "http://ranking.goo.ne.jp/rss/keyword/keyrank_all1/index.rdf"; XNamespace d = "http://purl.org/rss/1.0/"; var res = from item in feedXML.Descendants(d + "item") GridView1.DataSource = res; January 06 ASP.NET ルーティングMSDN を読んでいたら、ASP.NET ルーティングということで、URLの書き換え方法が載っていた。 http://msdn.microsoft.com/ja-jp/library/cc668201.aspx 昔調べた方法から、IIS7 対応もあり、だいぶ変わっているようなので調べてみた。そうしたら、ええ~~、こんな簡単にできようになっちゃたんだー!と感動して、ためしに動かしてみようとしました。すると、CategoryRouteHandler がありませんと怒られる。そりゃそうだ、どこにもそんなコードがない。あれ??ということで調べてみると、どっとねっとふぁんBlog の小野さんが で丁寧に解説してあった。さすが師匠wと感動する一方、やっぱりハンドラ書かないといけないのね。orz LinqDataSource によるメモリ内コレクションのデータへの接続http://msdn.microsoft.com/ja-jp/library/bb547113.aspx Default.aspx.cs にMoviewLibraryクラスを追加。 using System; namespace LinqDataSource } public class MovieLibrary public MovieLibrary() public string[] AvailableGenres GridViewを追加。新しいデータソースを選択。 LINQを選択。 データソースの構成ダイアログで、MoviewLibraryを選択。 データの選択の構成ダイアログで、テーブル、Select, GroupBy, Where, OrderBy を指定可能。 実行すればこのとおり。 生成されたWPFコードは、 <asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSource1"> 列名までしっかり処理されている。もう少し複雑なテーブルで試してみると、これがずいぶん便利だということに気が付く。 January 05 サービス参照の追加(VS2008) と Web参照の追加(VS2005)January 03 ZAM3Dが生成するXAMLをC#で実装するとインラインモデルは、こんな感じ。 private void Sample2()
{
this.viewPort3D1.Name = "ZAM3DViewport3D";
viewPort3D1.ClipToBounds = true;
viewPort3D1.Width = 400;
viewPort3D1.Height = 300;
PerspectiveCamera camera = new PerspectiveCamera();
camera.FarPlaneDistance = 10f;
camera.LookDirection = new Vector3D(2.05609, -1.21509, -2.52021);
camera.UpDirection = new Vector3D(0f, 1f, 0f);
camera.NearPlaneDistance = 2f;
camera.Position = new Point3D(-2.05609,1.21509,2.52021);
camera.FieldOfView = 39f;
viewPort3D1.Camera = camera;
ModelVisual3D modelVisual3D = new ModelVisual3D();
Model3DGroup model3DGroup = new Model3DGroup();
modelVisual3D.Content = model3DGroup;
Transform3DGroup transform3DGroup = new Transform3DGroup();
TranslateTransform3D translateTransform3D = new TranslateTransform3D(0f, 0f, 0f);
ScaleTransform3D scaleTransform3D = new ScaleTransform3D(1f, 1f, 1f);
AxisAngleRotation3D axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
RotateTransform3D rotateTransform3D = new RotateTransform3D();
rotateTransform3D.Rotation = axisAngleRotation3D;
transform3DGroup.Children.Add(translateTransform3D);
transform3DGroup.Children.Add(scaleTransform3D);
transform3DGroup.Children.Add(rotateTransform3D);
model3DGroup.Transform = transform3DGroup;
//////
AmbientLight ambientLight = new AmbientLight(Color.FromRgb(0x33, 0x33, 0x33));
model3DGroup.Children.Add(ambientLight);
DirectionalLight directionalLight1 = new DirectionalLight(Colors.White, new Vector3D(-0.6f, -0.5f, -0.6f));
model3DGroup.Children.Add(directionalLight1);
DirectionalLight directionalLight2 = new DirectionalLight(Colors.White, new Vector3D(0.6f, -0.5f, -0.6f));
model3DGroup.Children.Add(directionalLight2);
//////
Model3DGroup model3DGroupBox = new Model3DGroup();
Transform3DGroup transform3DGroupBox = new Transform3DGroup();
TranslateTransform3D translateTransform3DBox = new TranslateTransform3D(0f, 0f, 0f);
ScaleTransform3D scaleTransform3DBox = new ScaleTransform3D(1f, 1f, 1f);
AxisAngleRotation3D axisAngleRotation3DBox = new AxisAngleRotation3D(new Vector3D(0f, 1f, 0f), 0f);
RotateTransform3D rotateTransform3DBox = new RotateTransform3D();
rotateTransform3DBox.Rotation = axisAngleRotation3DBox;
TranslateTransform3D translateTransform3DBox2 = new TranslateTransform3D(0,0,0);
transform3DGroupBox.Children.Add(translateTransform3DBox);
transform3DGroupBox.Children.Add(scaleTransform3DBox);
transform3DGroupBox.Children.Add(rotateTransform3DBox);
transform3DGroupBox.Children.Add(translateTransform3DBox2);
model3DGroupBox.Transform = transform3DGroupBox;
/////
GeometryModel3D geometryModel3D = new GeometryModel3D();
MaterialGroup materialGroup = new MaterialGroup();
DiffuseMaterial diffuseMaterial = new DiffuseMaterial();
diffuseMaterial.Brush = new SolidColorBrush(Color.FromRgb(0xd3, 0xc8, 0xad));
materialGroup.Children.Add(diffuseMaterial);
SpecularMaterial specularMaterial = new SpecularMaterial();
specularMaterial.SpecularPower = 93f;
specularMaterial.Brush = new SolidColorBrush(Color.FromRgb(0x33, 0x33, 0x33));
materialGroup.Children.Add(specularMaterial);
geometryModel3D.Material = materialGroup;
////
GeometryModel3D geometryModel3DBack = new GeometryModel3D();
MaterialGroup materialGroupBack = new MaterialGroup();
DiffuseMaterial diffuseMaterialBack = new DiffuseMaterial();
diffuseMaterialBack.Brush = new SolidColorBrush(Color.FromRgb(0xd3, 0xc8, 0xad));
geometryModel3DBack.Material = materialGroupBack;
materialGroupBack.Children.Add(diffuseMaterialBack);
SpecularMaterial specularMaterialBack = new SpecularMaterial();
specularMaterialBack.Brush = new SolidColorBrush(Color.FromRgb(0x33, 0x33, 0x33));
specularMaterialBack.SpecularPower = 93f;
materialGroupBack.Children.Add(specularMaterialBack);
geometryModel3D.BackMaterial = materialGroupBack;
////
MeshGeometry3D meshGeometry3D = new MeshGeometry3D();
TypeConverter i32ColConv = TypeDescriptor.GetConverter(typeof(Int32Collection));
meshGeometry3D.TriangleIndices = (Int32Collection)i32ColConv.ConvertFromString("0,1,2 2,3,0 4,5,6 6,7,4 8,9,10 10,11,8 12,13,14 14,15,12 16,17,18 18,19,16 20,21,22 22,23,20");
TypeConverter vector3DColConv = TypeDescriptor.GetConverter(typeof(Vector3DCollection));
meshGeometry3D.Normals = (Vector3DCollection)vector3DColConv.ConvertFromString("0,0,-1 0,0,-1 0,0,-1 0,0,-1 0,0,1 0,0,1 0,0,1 0,0,1 0,-1,0 0,-1,0 0,-1,0 0,-1,0 1,0,0 1,0,0 1,0,0 1,0,0 0,1,0 0,1,0 0,1,0 0,1,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 ");
TypeConverter point3DColConv = TypeDescriptor.GetConverter(typeof(Point3DCollection));
meshGeometry3D.Positions = (Point3DCollection)point3DColConv.ConvertFromString("-0.5,-0.5,-0.5 -0.5,0.5,-0.5 0.5,0.5,-0.5 0.5,-0.5,-0.5 -0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,-0.5 0.5,-0.5,-0.5 0.5,-0.5,0.5 -0.5,-0.5,0.5 0.5,-0.5,-0.5 0.5,0.5,-0.5 0.5,0.5,0.5 0.5,-0.5,0.5 0.5,0.5,-0.5 -0.5,0.5,-0.5 -0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,-0.5 -0.5,-0.5,-0.5 -0.5,-0.5,0.5 -0.5,0.5,0.5 ");
geometryModel3D.Geometry = meshGeometry3D;
model3DGroupBox.Children.Add(geometryModel3D);
////
model3DGroup.Children.Add(model3DGroupBox);
modelVisual3D.Content = model3DGroup;
this.viewPort3D1.Children.Add(modelVisual3D);
} January 01 C++/CLI によるScreen Saver スケルトンコードWindows Mobile の Today のプラグインを実装しようと思うと、WnProc を実装する必要があり、C#だけでは実装できない。 http://msdn.microsoft.com/en-us/library/ms839442.aspx に、Creating a Pocket PC Today Screen Plug-in with the .NET Compact Framework という方法も載っているが、これだと共有メモリを使ってHTMLをレンダリングさせる方法なので、かえって見通しが悪そう。これなら、直接C++/CLIで実装して、一部を C#で書いたほうが楽そう。ただ、TodayのプラグインがC++/CLIで実装可能かどうか・・・C++/CLIでも実装可能なら、一部を C# で書くことも可能なので、ちょっと込み入った実装もだいぶ楽になるはず。 少し調べていたら、 http://www.atmarkit.co.jp/fdotnet/special/cppcli/cppcli_01.html に「いままたC++が熱い!「C++/CLI」として大進化したVisual C++ 2005」の記事があり、C++/CLI によるScreen Saver のサンプルがあったので、試してみた。 結果はWinProc をC++/CLIで動かすことができる。ということは、おそらく Windows Mobile の Today のプラグインも同様に動くと思われると、思ったが、スマートデバイスのプロジェクトテンプレートでは、C++/CLI がサポートされないみたい orz ピーデー 川俣 晶さんがアップしているコードを VS2008用にちょっと修正したので、とりあえずメモ。
#include <stdafx.h> #using <mscorlib.dll> using namespace System; |
|
|