カテゴリ:C#( 30 )

PowerShell を何に使うか

PowerShell を使うと、レジストリの管理や、プロセスの管理などなんでもできるようだが、アマチュアユーザにはちょっと縁がない。

単なるパソコンのユーザの立場から嬉しいのは、様々なフィルターを使ってファイルを検索する機能だろう。たとえばカレントディレクトリのファイルのリストは、

PS > Get-ChildItem

で取得できる。エイリアスがあるので、ls や dir も使うことができる。

このうち、拡張子が .exe のファイルだけを取り出したいときはフィルターをかけて、

PS > Get-ChildItem | where {$_.Extension -eq ".exe"}

でとりだせる。".exe" ファイル以外を取り出したいときは、

PS > Get-ChildItem | where {$_.Extension -ne ".exe"}

で、できる。キーワード whereは短縮形で、?が使える。また、サブディレクトリまで検索する場合は -Recurse オプションを指定する。

PS > Get-ChildItem -Recurse | ? {$_.Extension -eq ".exe" }

条件にマッチするアイテムを取り出すフイルターと共によく使われるのがソート・フィルタだ。アイテムのソートは、Sort-Object コマンドレットが使われる。

PS > Get-ChildItem | Sort-Object Length

逆順にしたいときは、

PS > Get-ChildItem | Sort-Object Length -Descending

条件マッチやソートに使われるオブジェクトのプロパティを知りたいときは、次のようにする。

PS > Get-Item .\ | Get-Member

これを見ると、最後のアクセスタイムが LastAccessTime プロパティに入っているので、最も最近アクセスしたファイルを知りたいときは、

PS > Get-ChildItem | Sort-Object LastAccessTime

で取得したリストの最後を見れば良い。

また、自前のフィルターは、filter キーワードで作成できるので調べてほしいが、上のやり方だけでも随分色々なことができる。パイプラインにオブジェクトを流すという方式は、まだまだ思いも掛けない用途が見つかるかもしれない。

PowerShell を使いたくて昨日購入した58000円のGatewayのパソコンは、既に、ruby, Haskell Platform, Racket(scheme), Xampp(Apache, php, perl), OpenOffice, java, csc(C#), rhino(javascript) などでてんこ盛りになってしまった。これらを全部 PowerShell からコントロールできる。Windowsでこれだけプログラムの道具が揃う時代になったのかと感慨深いが、PowerShell を何に使うかというイメージもできたので、本当にプログラムネタはしばらくお休みにします。
[PR]
by tnomura9 | 2011-01-31 12:32 | C# | Comments(0)

PowerShell が .NET 対応であることの意味

PowerShell は .NET 対応だが、それはどういうことを意味しているのだろうか。

PowerShell から .NET のオブジェクトを使うことができるのを体験するために、Get-Item で 適当なファイルのファイル情報を取得してみる。

PS C:\Users\*****\Documents\PowerShell\Functions> $item = Get-Item .\functions.ps1

取得した $item は .NET オブジェクトなので、プロパティやメソッドを持っている。それを、Get-Member コマンドレットで表示してみる。

PS C:\Users\*****\Documents\PowerShell\Functions> $item | Get-Member


TypeName: System.IO.FileInfo

Name MemberType Definition
---- ---------- ----------
Mode CodeProperty System.String Mode{get=Mode;}
AppendText Method System.IO.StreamWriter AppendText()
CopyTo Method System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo CopyTo(s...
Create Method System.IO.FileStream Create()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
CreateText Method System.IO.StreamWriter CreateText()
Decrypt Method System.Void Decrypt()
Delete Method System.Void Delete()
Encrypt Method System.Void Encrypt()
Equals Method bool Equals(System.Object obj)
GetAccessControl Method System.Security.AccessControl.FileSecurity GetAccessControl(), System.Secur...
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetObjectData Method System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo in...
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
MoveTo Method System.Void MoveTo(string destFileName)

中略

Attributes Property System.IO.FileAttributes Attributes {get;set;}
CreationTime Property System.DateTime CreationTime {get;set;}
CreationTimeUtc Property System.DateTime CreationTimeUtc {get;set;}
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property System.String DirectoryName {get;}
Exists Property System.Boolean Exists {get;}
Extension Property System.String Extension {get;}
FullName Property System.String FullName {get;}
IsReadOnly Property System.Boolean IsReadOnly {get;set;}
LastAccessTime Property System.DateTime LastAccessTime {get;set;}
LastAccessTimeUtc Property System.DateTime LastAccessTimeUtc {get;set;}
LastWriteTime Property System.DateTime LastWriteTime {get;set;}
LastWriteTimeUtc Property System.DateTime LastWriteTimeUtc {get;set;}
Length Property System.Int64 Length {get;}
Name Property System.String Name {get;}
BaseName ScriptProperty System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Re...
VersionInfo ScriptProperty System.Object VersionInfo {get=[System.Diagnostics.FileVersionInfo]::GetVer...

相当数あるが、いったい何個あるのだろうか。

PS C:\Users\*****\Documents\PowerShell\Functions> ($item | Get-Member).Length
48

48個もあることがわかる。プロパティのひとつ LastAccessTime を調べてみよう。

PS C:\Users\*****\Documents\PowerShell\Functions> $item.LastAccessTime

2011年1月30日 19:25:04

プロパティを使って、ディレクトリ内の .txt 拡張子を持ったファイルを検索することもできる。

PS C:\Users\*****\Documents\PowerShell\Functions> Get-ChildItem C:\Users\*****\Documents | where {$_.Extension -eq
".txt"}


ディレクトリ: C:\Users\*****\Documents


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2011/01/30 18:31 402 プログラム言語の学び方.txt

同じ発想で、Get-ChildItem のエイリアスにはどんなものがあるか調べてみる。

PS C:\Users\*****\Documents\PowerShell\Functions> Get-ChildItem Alias: | where {$_.Definition -eq "Get-ChildItem"}

CommandType Name Definition
----------- ---- ----------
Alias dir Get-ChildItem
Alias gci Get-ChildItem
Alias ls Get-ChildItem

Unix のシェルでは、ls | grep *.txt のように文字列処理でやっていたようなフィルタをオブジェクトのプロパティでできるので便利だ。

PowerShell が .NET 対応であることの意味は、Get-ChildItem のようなコマンドレットから返される戻り値がオブジェクトであるということと、そのオブジェクトのプロパティを使ったいろいろなフィルタ処理が簡単にできるということだ。これが、パイプにオブジェクトを流し込むことができるということの意味だ。
[PR]
by tnomura9 | 2011-01-31 08:14 | C# | Comments(0)

C# のインタラクティブ・シェル csharp

Linux の .Net 環境 Mono をインストールすると、C# のインタラクティブ・シェル csharp が付いてくる。Ubuntu で Mono をインストールするには、Ubuntu ソフトウェアセンター>開発ツール>Mono/CLI の検索で mono-complete を検索してインストールするとよいようだ。

Mono がインストールされていれば端末エミュレータで、csharp と入力するとインタラクティブシェルが起動する。

tomokiyo@tomokiyo-laptop:~$ csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> Console.Write("name: "); string name = Console.ReadLine(); Console.WriteLine("Hello, {0}", name);
name: Dolly
Hello, Dolly
csharp> "Hello, Dolly".Length;
12

上の例のように、コンパイルしないでも C# の機能を試すことができるのは非常にうれしい。メソッドなのかアトリビュートなのか迷うことは多いので、ちょっと入力するだけで確認できるのは学習の壁を低くしてくれる。

csharp> help;
"Static methods:
Describe(obj) - Describes the object's type
LoadPackage (pkg); - Loads the given Package (like -pkg:FILE)
LoadAssembly (ass) - Loads the given assembly (like -r:ASS)
ShowVars (); - Shows defined local variables.
ShowUsing (); - Show active using decltions.
Prompt - The prompt used by the C# shell
ContinuationPrompt - The prompt for partial input
Time(() -> { }) - Times the specified code
quit;
help;
TabAtStartCompletes - Whether tab will complete even on emtpy lines
"
いまのところは、コンパイルされたパッケージしか読み込むことができないようだが、将来的には、自分のプログラムを記述したソースファイルを読み込んでコンパイルして端末から使えるようになるかもしれない。まだ、開発途上のようだ。

PowerShell にしても、csharp にしても、インタラクティブ・シェルはプログラムの学習や開発を非常に楽にしてくれる。インタラクティブ・シェルで開発して、完成したらコンパイルして使うという作業の流れは、これから本流になっていくのかもしれない。
[PR]
by tnomura9 | 2011-01-30 10:54 | C# | Comments(0)

PowerShell で複数行のコマンドをプログラムする。

対話型のシェルで小さいプログラムをテストするとき、煩わしいのがプログラムをファイルに作成するという操作だ。ほんの数行のプログラムをテストしたいのに、いちいちエディタを立ち上げるのはかなり面倒に感じる。

PowerShell は原則として一行のコマンドレットしか実行できないが、Invoke-Expression とヒアドキュメントを組み合わせると、次の実行例のように、複数行にわたるスクリプトを実行することができる。

PS > Invoke-Expression @'
>> $total = 0
>> for ($i = 1; $i -le 10; $i++) {
>>     $total += $i
>> }
>> Write-Host "total = ", $total
>> '@
>>
total = 55

PowerShell では Add-Type コマンドレットを使うと、C#のソースも実行させることができるので、上のプログラムはC#を使って次のように実行することもできる。

PS > $source = @"
>> public class MyClass
>> {
>>    public static int Total()
>>     {
>>         int total = 0;
>>         for (int i = 1; i <= 10; i++)
>>             total += i;
>>         return total;
>>     }
>> }
>> "@
>>
PS > Add-Type -TypeDefinition $source
PS > [MyClass]::Total()
55
[PR]
by tnomura9 | 2011-01-30 00:00 | C# | Comments(0)

PowerShell でC#のコンパイル

PowerShell がすっかり気に入ったので、C#も PowerShell からコンパイルしたくなってきた。そこで、csc.exe のパス

C:\Windows\Microsoft.NET\Framework\v4.0.30319

を環境変数 PATH に追加し、Vim7.3をダウンロードしてきてインストールし、vim.exe のパス

C:\Program Files\Vim\vim73

を PATH に追加した。

それから、PowerShell を起動し、

> vim hello.cs

hello.cs の内容をつぎのように編集し、

namespace Hello {
  using System;

  class Hello {
    public static void Main() {
      Console.WriteLine("hello, world");
    }
  }
}

次のように、コンパイルして実行した。

> csc hello.cs

> .\hello.exe
hello, world

Windows 7 への愛しさが倍増した。(愛しさと、切なさと、心強さと... )
[PR]
by tnomura9 | 2011-01-26 19:09 | C# | Comments(0)

PowerShell

Windows のコマンドプロンプトに変わる新しいシェル PowerShell というのがあるのを知った。Windows 7 には標準でついている。

Uniix のパイプラインのデータフォーマットであるキャラクターストリームの代わりに、オブジェクトをパイプに流し込めると聞いて興味が湧いて調べてみた。Unixのシェルと操作感はかわりないが、.Net のオブジェクトを利用することができる。

パイプラインにオブジェクトを流し込めるというのは、将来的には、モジュール化したプログラムをつなぎあわせて高度の処理を迅速に行うことができるようになる可能性が考えられる。Unix のコマンドをパイプラインでつなぎあわせて使うのと次元の違う使い方ができるようになるかもしれない。

例えば、グラフ作成モジュールがあって、表計算のデータも、ワープロのデータも全てそのモジュールで処理できるようにすれば、表計算やワープロの重さを劇的に改善して操作性を上げることができるようになるだろう。

シェルとしての使い方の解説は、マイクロソフトのページWindows PowerShell でのスクリプティングに揃っている。

スクリプトとしての概要についてはPowerShell基礎文法最速マスターが便利だ。細工をすれば、ユーザ定義のクラスも作れるようだ。

書籍は『Windows PowerShell ポケットリファレンス』牟田口大介著が一押し。

使ってみた印象はなかなかいい。.NET に統合されているのも便利だ。Windowsマシンが、.NET を中心として、アマチュアプログラマにもプログラムできる魅力的な製品になってきた。.NET 関連の学習専用にノートパソコンが欲しくなってきた。
[PR]
by tnomura9 | 2011-01-22 12:52 | C# | Comments(0)

紙copi lite

C# の概要が分かったが、なかなかさあプログラムを作るぞという気にならない。まともなものを作れるようになるのに膨大な時間がかかりそうだし、壁もいくつも越えなければならなそうだ。それに、使いたい道具は有償、無償を含めて完成度の高いものが既に存在しているので、探したほうが早いかなと思ってしまう。

そうだ、探したほうが早いかもしれないと思いついて探し出したのがこれ、

紙copi

Webページやメモをスクラップすることのできる、スクラップブックソフトだ。無償版の 紙copi lite もある。Firefox のアドオンをインストールすると、右クリックでホームページをスクラップできる。選択した範囲だけをスクラップするのも可能だ。ファイルを保存するのに、ファイル名を入力する必要もない。

使い勝手のほうがまだ分からないので、しばらく無償版で試用してみたい。無償版では、サブディレクトリが作れないので本格的に使うには有償版が必要かもしれない。

本当にやりたいのは、情報の整理だし、Linux の CUI ならツールの組み合わせが簡単にできるので GUI の必要性はあまり感じなかった。Linux なら、スクリプトを使ってツールを組み合わせることもできるので、GUIがなくてもあまり不自由を感じることがない。しかし、いかんせん、Linux のデスクトップは相変わらずマイナーだ。仕事にはどうしても Windows を使わなくてはならない。したがって、こういうソフトはありがたい。

とはいうものの、CUI は Windows では役に立たないので、GUI のプログラムも作れるようになるのも必要かもしれないと思った。それで、Visual C# の方もぼちぼちプログラムを作っていこうと思っている。

アイディアの整理だけなら Linux が便利なのだけれど、仕事では Windows を使わなければならないことが多いので、なかなか悩ましい。
[PR]
by tnomura9 | 2010-02-02 07:30 | C# | Comments(0)

C#からC/C++のライブラリを使う方法

C#からCのライブラリを使いたい場合は、C++/CLI というソフトを経由するといいらしい。CodeZine の次の記事に紹介があった。

C++/CLIによるCライブラリの.NET化
[PR]
by tnomura9 | 2010-02-01 05:56 | C# | Comments(0)

結局C#とはどういうものか

Visual C# で簡単なプログラムを作り、.cs ファイルの記述がどうなっているのかを探索して、C#のプログラムの雰囲気を調べてきた。

それでは C#/.NET とはどういうプログラム言語なのかということになるが、使ってみた感じや、マイクロソフトのチュートリアルなどを見ると、プログラムの部品化できるものは徹底的に部品化しようとしている方針のように見える。GUIなどは、極力GUIで基本的に動くものを作り、コーディングの手間を省くことができる。

たとえば、基本的な機能が既にプログラムされたコンポーネントを使うと、簡単なテキストエディタのようなものはほとんどGUIで設計できる。また、GUI に限らず、データベースとのアクセスや、ウェブアプリの開発も、使い回しのきくプログラムの部品は極力使い回して使用するという考え方だ。

基本的な機能はかなりのものまで、コンポーネントが既に持っている。たとえば、テキストボックスはそのままで、Ctr-C, Ctr-V などのショートカットキーによるコピーアンドペーストに対応している。そうして、個々のプログラムの細かいチューニングについてはオブジェクトのプロパティの変更で対応している。それを、可能にしているのが、.NET の完全にオブジェクト指向化したクラスライブラリだ。

C#は、.NET のクラスライブラリを最も簡潔に取り扱えるように設計されているとともに、オブジェクト指向プログラムで発生しやすいオーバーヘッドなどの問題を解決しようとしている。

コンポーネントを使ったプログラムは誰が作っても同じようなプログラムになりやすいが、プログラムそのものの表現力より、多少画一的ではあっても目的の情報処理を効率的に作ることを優先している。良くも悪くも実務的な印象を受ける。プログラミングをアートととらえたい人には物足りないかもしれない。

こういうC#の特色については、実際の事例を使って、何ができるのか、何を目的としてどういう使い方をするものなのかなどという議論をすべきだが、それは、管理人には荷が重い。

Visual C#は日曜大工的で作る本棚のようなプログラムも書けるが、高層ビルディングも建てることができる。このような高層ビルディング的なプログラムを作るためには、別の知識がいるが、日曜大工をやっている限りは必要ないし、現場にいないと学習も難しい。

そいう訳で、管理人のC#関連の記事の最後として、C#とは何かがわかるサイトを紹介する。いずれにせよ、Visual C# のような開発環境が簡単に手に入るようになったおかげで、コンピュータ大好き人間にとって Windows OS の魅力が倍増したことは間違いない。

Visual C# デベロッパーセンター: マイクロソフトの公式サイト

.NET Framework ラーニング: 同じくマイクロソフトのサイト

私がJavaからC#に乗り換えた10の理由: 開発者から見たC#の特色

C# によるプログラミング入門: C#の言語仕様の実例入りの解説
[PR]
by tnomura9 | 2010-01-31 08:43 | C# | Comments(0)

プログラムファイルの構成

Visual C# で、新しいプロジェクトを作り、フォームの上にボタンをひとつだけ貼付け、そのボタンをダブルクリックして、イベントハンドラ button1_Click () を作成した時のプログラムファイルの構成を再度概観してみた。

ファイルは分割されているが、統合されて一本のプログラムリストとして扱われる。インクルード文でファイルを読み込むわけではないので、分割ファイル間の依存関係は namespace (名前空間)で判別される。

まずはファイルの依存関係。

Program.cs
  Form1.cs
    Form1.Designer.cs

名前空間の階層構造。

namespase Learn
{
  static class Program
  {
    [STAThread]
    static void Main() { Application.Run(new Form1()) }
  }

  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e) { ... }
  }

  public partial class Form1
  {
    private System.ComponentModel.IContainer components = null;
    protected override void Dispose(bool disposing) {}
    private void InitializeComponent() { ... }

    this.button1 = new System.Windows.Forms.Button();
    System.Windows.Forms.Button button1;
  }
}

どういう事を実行しているかというと、
1. System.Windows.Forms.Form クラスから導出して Form1 クラスを作る。
2. Form1 の上にボタンを作成し、ボタンのクリックをイベントハンドラと関連付ける InitializeComponent() メソッドを作る。
2. button1 ボタンが参照出来るように、フィールド button1 を作る
3. ボタンがClick された時のイベントハンドラ button_Click を定義する。
4. Learn.Program.Main() を呼び出す。
5. Learn.Program.Main() は、System.Forms.Application.Run() を呼び出す。
6. System.Forms.Application.Run は引数に Learn.Form1 のインスタンスを必要とするので new Form1() で作る。
7. Form1 クラスのコンストラクタ Form1() は Learn.Form1.InitializeComponent()
で、フォームのコンポーネントの初期化をする。
8. InitializeComponent() が実行されたら、Application.Run() の中でプログラムがイベント待ちの待機状態になる。

これだけのことをするプログラムがフォームデザイナで自動生成されていたので、イベントハンドラを記述するだけでプログラムが出来上がってしまうような、安易な印象を持ってしまったのだ。逆に言うとその分プログラム作成の効率が劇的に上がっている事になる。

C#のプログラムをスクラッチからつくるのは容易ではない。Visual C#でプログラムを作ると、定型的な部分はプログラムが作ってくれるので、プログラマの仕事はきちんと動くプログラムを改造するだけになる。しかし、どの部分の改造を自分がやっているのかは、自覚的しておく必要がある。

C# や .NET を全て理解してからプログラムを作ることは不可能ではないが事実上は無理なので、こういう自動作成されたプログラムの改造に頼らなければならないが、自動作成されたプログラムの不可解な部分をできるだけ少なくする努力は必要だろう。
[PR]
by tnomura9 | 2010-01-30 07:57 | C# | Comments(0)