カテゴリ:.NET( 18 )
64bitOSでAnyCPUでコンパイルした32bitプロセスを動かす
AnyCPUでビルドした場合、動作する環境によってプロセスのビット数がことなる。
  • 64ビットOSでは64ビットプロセスとして動作する。
  • 32ビットOSでは32ビットプロセスとして動作する。


では、64ビットで32ビットプロセスを動かすにはどうしたらいいか?
これは、CorFlagsコマンドを使う。

VisualStudio2008の場合は以下にある。
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\CorFlags.exe

VisualStdioをインストールしたときにプログラムファイルに記述されるコマンドプロンプトではパスが通っているのでそこからおこなうといい。


そこで次のようなコマンドを実施する

CorFlags /32BIT+ TestR.exe

VS2012では /32BITREQ+ フラグになる。

これを関連するDLLを含めておこなう。
AnyCPUでビルドされているDLLは、ExEのプラットフォームに合わせて動作するので不要。
もしx64でビルドされていた場合は、Exeと同様に32ビットフラグを付与すること。

もし強い名称で署名をされている場合は、/Force オプションを付与すること。

CorFlags /32BIT+ /Force RDotNet.dll



[PR]
by mima_ita | 2013-11-30 03:14 | .NET
NMecabを用いてVBAやWSHで形態素解析を行なう
概要

b0232065_21104163.png
.NET Frameworkで作成されたクラスライブラリのNMecabを、ActiveXを経由してVBAやWSHなどから形態素解析を行なうことを目的とします。

NMecabは下記のページで開発されています。
https://sourceforge.jp/projects/nmecab/


ダウンロード

ExcelNMeCabCom.zip


使用方法

このプログラムは.NETFramework2.0の32ビットプロセスで動作します。

もし、64ビットのプロセスで使用したい場合は、NMeCabCom.dllとLibNMeCab.dllを64ビットでビルドしなおしてください。

インストールを行なうにはNMeCabCom\binにあるsetup.batを管理者権限で実行してください。

これにより、参照設定にNMeCabComが表示されるのでチェックをいれてください。
b0232065_20563390.png
その後、以下のようなコードを記述します。
    Dim t As New NmcTagger
    Dim c As NmcNodeCollection
    Dim p As New NmcParam
    p.dicdir = "C:\back\NMeCabCom\bin\ipadic"
    Call t.Create(p)
    Set c = t.Parse("私の名前はLです")
    Dim i As Long
    For i = 0 To c.Count - 1
        Debug.Print c.GetItem(i).Surface & " " & c.GetItem(i).Feature
    Next
NmcTaggerに渡すNmcParamにはシステム辞書とユーザ辞書を指定できます。
ユーザー辞書の作成については、本家のMecabのホームページを参考に作成してください。



WSHなどで、CreateObjectで遅延バインディングする場合は以下のようになります。
dim t
dim ret
dim i
dim p
dim node
set t = CreateObject("NMeCabCom.NmcTagger")
WScript.Echo TypeName(t)

set p = CreateObject("NMeCabCom.NmcParam")

p.dicdir = "./ipadic"
p.userdic = ""
t.Create(p)

set ret = t.Parse("This is a pen.")
WScript.Echo TypeName(ret)

For i = 0 To ret.Count- 1
  WScript.Echo TypeName(ret.GetItem(i))
  WScript.Echo ret.GetItem(i).Surface
Next

もし、アンインストールを行い対場合はuninstall.batを管理者権限で実行してください。

NMecabのユーザー辞書
NMecabはapp.configのUserDicに辞書のパスを指定することでユーザー辞書を指定できますが、少なくとも、当方の環境ではTokenize.Openで落ちました。

以下のような修正を行えば正常にユーザー辞書が使用できます。

修正前:
for (int i = 1; i <= param.UserDic.Length; i++) 

修正後:
for (int i = 0; i < param.UserDic.Length; i++)


[PR]
by mima_ita | 2013-11-25 21:07 | .NET
C#で実装したコードをVBSから使う際の注意点
次の点に注意しなければならない。

Uint、ULONG等のUnsignedの変数は利用できない。

VBAやVBSはUnsignedをサポートしていないので、ULONGなどのインターフェイスは使用できない。


作成したCOMのCPUにあわせて実行するCScriptを切り替える必要がある。
64ビットマシンにはVBScriptを動かすCScriptが二種類存在する。
32ビット用のものはC:\Windows\syswon64\cscript である。
64ビット用のものはC:\Windows\System32\Cscript である。
もし、作成したCOMと実行するCScriptのプロセスのビットが異なる場合、登録したはずのCOMが見つけられず下記のエラーが発生する

C:\dev\NMeCabCom\bin\sample.vbs(6, 1) Microsoft VBScript 実行時エラー: ActiveX コンポーネントはオブジェクトを作成できません。: 'NMeCabCom.NmcTagger'

オブジェクトの配列は返せない

以下のようなCOMのインターフェイスがあったとする。

    public interface INmcTagger
    {
        string GetModulePath();
        void Create(NmcParam p);
        NmcNode[] Parse(string text);
    }

これはVBAやC#などの型を明示できる言語では適切に処理できる。
Dim ret As NmcNode()
ret = t.Parse("This is a pen.")
しかし、VBSの場合、型が明示できないため、Unknownとなり処理できなくなる。
Dim ret ' As NmcNode()
ret = t.Parse("This is a pen.")
WScript.Echo TypeName(ret) ' Unknownとなり、以降処理できない。
こういう場合は、配列を管理するクラスを作成してそれを利用する
    public interface INmcNodeCollection
    {
        int Count { get; }
        NmcNode GetItem(int index);
    }
配列ではないオブジェクトを返した場合は、VBSでも処理ができる
set ret = t.Parse("This is a pen.")
For i = 0 To ret.Count- 1
  WScript.Echo TypeName(ret.GetItem(i))
  WScript.Echo ret.GetItem(i).Surface
Next




[PR]
by mima_ita | 2013-11-25 17:36 | .NET
C#で実装したコードをVBAとかVBから使う方法
■環境
 Visual Studio2008 Pro
 .NET Framework 2.0 を対象とする。
 32ビットのOffice2010から使用すること



■手順
1. Visual Studio 2008 を管理者権限で起動する。
 これはCOM登録時にレジストリを変更するため。
 


2.プロジェクトの追加で「.NET Framework 2.0」 と 「クラスライブラリ」を選択
b0232065_03304192.png


3. ビルドにてプラットフォームのターゲットをx86とする。
b0232065_03320476.png



4. ビルドにてCOM相互運用機能の登録にチェックをつける。
b0232065_03335478.png


5. アプリケーションのアセンブリ情報で、「アセンブリをCOM参照可能にする

b0232065_03340744.png

6. 公開したいインターフェイスとその実態について以下のように記述する
using System.Runtime.InteropServices;
namespace NMeCabCom
{
    [ComVisible(true)]
    public interface INmcTagger
    {
        void Create();
        NmcNode[] Parse(string text);
    }
   
    [ClassInterface(ClassInterfaceType.None)]
    public class NmcTagger : INmcTagger
    {
        private MeCabTagger nmcab;
        public NmcTagger()
        {
        }

        public void Create()
        {
            MeCabParam p = new MeCabParam();
            p.DicDir = @"C:\dev\NMeCab\dic\ipadic";

            this.nmcab = MeCabTagger.Create(p);
        }

        public NmcNode[] Parse(string text)
        {
            List<NmcNode> result = new List<NmcNode>();
            if (this.nmcab == null)
            {
                return result.ToArray();
            }
            MeCabNode node = this.nmcab.ParseToNode(text);
            while (node != null)
            {
                result.Add(new NmcNode(node));
                node = node.Next;
            }
            return result.ToArray();
        }
   
    }
}
まず、公開するインターフェイスの直前に「ComVisible(true)」と記述する。
    [ComVisible(true)]
    public interface INmcTagger
    {
        void Create();
        NmcNode[] Parse(string text);
    }


そして、そのインターフェイスの実装部分はClassInterfaceType.Noneとする。
    [ClassInterface(ClassInterfaceType.None)]
    public class NmcTagger : INmcTagger



7. ビルドを行うことでCOMの登録まで行われる


8. ExcelVBA側で参照設定してやれば、使用できるようになる
b0232065_03370741.png
b0232065_03373653.png







■別の環境への適用方法

.NET Frameworkのフォルダに存在するregasmを使用する。
作成したdllに対して /tlb/codebase を付与してregasmを実行する。
regasmは各バージョンの.NETに存在する。

SET BIN=C:\Windows\Microsoft.NET\Framework\v2.0.50727

REM 登録
%BIN%\regasm  C:\dev\NMeCabCom\NMeCabCom\bin\Debug\NMeCabCom.dll /tlb /codebase


この際、以下のメッセージが出力される場合がある。
「RegAsm : warning RA0000 : 署名されていないアセンブリを /codebase を使用して登録すると、同じコンピュータにインストールされるその他のアプリケーションとの競合が生じる可能性があります。/codebase スイッチは署名されたアセンブリのみに使用できます。アセンブリに厳密な名前を付けて、再登録してください。」

これは、警告だけであり、COMの登録はされている。
この警告を消すには、プロジェクトの設定で「署名」→「アセンブリの署名」 厳密な名前のキーファイルを選択する必要がある。

b0232065_03400617.png


依存するすべてのDLLが同様に厳密な名前を有しなければならないので気をつけること。


■COMの削除方法
下記の/tlb と /unregister を付与したregasmコマンドを実行後、ファイルを消す

regasm /tlb C:\dev\NMeCabCom\NMeCabCom\bin\Debug\NMeCabCom.dll  /unregister




[PR]
by mima_ita | 2013-11-23 03:42 | .NET
複数ネットワークアダプタがある場合のUDPを用いたマルチキャスト
複数ネットワークアダプタが存在する場合で、UDPをマルチキャストで送信するには、使用するネットワークアダプタ上の自分のIPアドレスをUdpClientのコンストラクタで指定しなければならない。

C#のコード例:

IPEndPoint localEp = new IPEndPoint(this.mLocalIP, 0);
udp = new UdpClient(localEp);
udp.Send(stream.ToArray(), (int)stream.Length, remortEP);



http://msdn.microsoft.com/ja-jP/library/k227d11f.aspx


これを行わないと、マルチキャストを行っても意図しないネットワークアダプタ側に送信されて、受信側に届かなくなる。
[PR]
by mima_ita | 2013-11-12 16:41 | .NET
C#のコードからドキュメントを生成する方法
C#のコードからドキュメントを作成する方法はいくつかある。
無料でできるほうほうとしては、以下の選択ができる。

Doxygen
・sandcastle
Sandcastle(XMLコメントからAPIヘルプ生成)


DoxygenはGraphVizと連携することでクラス図とコールグラフを作成できる。
mscgen記法でシーケンス図の記述することも可能である。
また、XMLコメントを解析してくれる

実行ファイルを解析しているわけではないので、コメントとかに誤りがあると正常に動作しない。

sandcastleはMSDN風のヘルプを作成してくれる。
実行ファイルを解析して継承関係などを調べているようだが、クラス図やコールグラフの自動生成は行なわない。

開発中のドキュメントとして使用する場合、Doxygenを使用したほうが使いやすそうだ。
[PR]
by mima_ita | 2013-09-19 21:26 | .NET
C# で外部プロセスを起動するときの注意。
・コマンドライン引数の文字コードは変更できない。
 たとえば、UTF-8をコマンドライン引数に受け取るプログラムを起動しようとした場合、正確に動作しない。
 

・起動するプロセスの環境変数を設定できる。ただしそれは全て小文字である。
 StartInfo.EnvironmentVariablesは環境変数をしていできる。
 しかしこれはStringDirectoryクラスであり、キーとなる環境変数は全て小文字になる。

 Windowsの環境変数は大文字、小文字を区別しないため、.NETフレームワーク同士のプロセスを起動するには問題にならない。
 しかし、Cygwinなどで作成したプロセスを起動使用とした場合、大文字の環境変数が絶対に渡せなくなることになる。
 なお、回避する方法として、以下のようなバッチファイルを作成してそれを実行することにした。

 参考:環境変数を指定して同じディレクトリのrcs.exeを起動するバッチファイル
 
@echo off
SET LANG=ja_JP.cp932
%~dp0\rcs.exe %*

[PR]
by mima_ita | 2013-09-19 00:34 | .NET
UTF8を表示するコマンドプロンプトを作ってみた
■目的
WindowsでPythonとかを使っているとUTF8の文字が化けて出力されて厳しいので、コマンドプロンプトの出力をUTF8に変換するコマンドプロンプトもどきをつくってみた。

ばけちゃっている日本語が・・・
b0232065_14551822.png


ちゃんと表示されるよ、ジョニー!
b0232065_14572678.png

上のほうのテキストボックスにコマンドプロンプトに発行したい命令を入力してEnterキーを押すと結果がかえってくる。

■ダウンロード
http://needtec.sakura.ne.jp/testprog/Utf8Cmd.zip
 Windows7 64bitの32bitアプリケーションで動作確認

■制限
 ・標準出力とエラー出力をUTF8にしているだけだから、普通のコマンドプロンプトで表示される日本語はばける
 ・標準入力をUTF8でやるのはむりでした。

■別解
 「コマンドプロンプト と UTF8」FineView Software Labs様より

More
[PR]
by mima_ita | 2013-05-30 15:13 | .NET



実験ですお
検索
カテゴリ
最新の記事
.NET4.5におけるasy..
at 2014-07-02 00:46
.NETでTwitterを検..
at 2014-06-29 00:49
Redmineのプラグインで..
at 2014-06-28 03:29
IO.popenのwrite..
at 2014-06-28 03:25
RedmineのWikiでU..
at 2014-06-28 03:16
以前の記事
最新のトラックバック
その他のジャンル
ブログパーツ