[ カテゴリー » PC関連 ]

頼むから持ちこたえて

blog20071104-PSU-BlackField

金曜日、突如デスクトップPCが青画面を連発するようになり、焦る。写真はそのときの異常さを示すもの。別に真っ暗な戦闘フィールドにいるわけでなく、他の人は草原が映っているはず。しかも私動けないしT_T。オーバークロックしていたのを定格に戻してもダメ。Windows起動時すら青画面になるため、OSかハードウェアなんだろうと。

最終的には3枚あるDDRメモリの挿し位置を変更することで解決。この方法は結構有効で、アクセスが不安定なメモリをCPUに近い方に挿すと、実用的なレベルになることがあります。DDRでこのありさまですから、DDR2/3を使用している自作PCにはダメ元でお勧め。まぁ、ぎりぎりアウトなため不安定になっていたのを挿し替えでぎりぎりセーフにしたわけですから、危うさは内に秘めているのでしょうけど。

以前にも書きましたがこの自作デスクトップ、AthlonXP 1800+(オーバークロックで2100+相当)/Socket A/DDR/AGP/パラレルATAと古い規格の塊で、マザーLink やCPUがお亡くなりになった日には、全交換は必至。せめて新Intel Core2(Penryn)やAMD Phenomが出るまで持ちこたえたいところ。

といっても、今で十分ゲームできているAthlon XPと似たような/上のシングルスレッド性能のCPUがローエンドで売っている(しかもDual Core)ので、たぶん新Core2もPhenomも買わないだろうな。

— posted by mu at 10:31 am   commentComment [0]  pingTrackBack [0]

PowerShell automationでスクリプト関数を使う

これLink の続き。ようやくVB.NET/C#.NETからPowerShellのスクリプト関数を定義して実行する目処がつきました。

内容は長いのでこちらにLink

— posted by mu at 10:04 pm   commentComment [0]  pingTrackBack [0]

.NETから可変引数のCOMメソッドを呼ぶ

先日Link の続き。未だSystem.Management.Automation.RunspaceにPowerShellスクリプト関数を定義して実行する方法がわからないので(2009/4/3 分かりましたLink )、COM実装のMSScriptControl.ScriptControl使用に方針変更。

VB6ならば以下のようにすれば使えます。
  1. Microsoft Script Control 1.0を参照設定
  2. MSScriptControl.ScriptControlクラスのインスタンスを作成
  3. Languageプロパティに言語を指定(今回は"VBScript")
  4. AddCodeメソッドで関数を定義する
  5. Runメソッドで定義した関数を呼ぶ

.NET上で作成したCOMインスタンスは開放処理しないとメモリに残り続けるLink という手間はあるようですが、.NET上でもCOMは.NET Frameworkとほぼ等価に扱えるため、同じ手法で実行できるはず。

が、トラブる。Runメソッドを呼ぶ段階になると

System.ArgumentException: HRESULT からの例外: 0x800A01C2 場所 MSScriptControl.ScriptControlClass.Run(String ProcedureName, Object[]& Parameters)

なる例外を出してしまいます。原因はRunメソッドが第2引数以降を可変長引数(VBでいうParamArray)を取るため。これの扱いは
環境 可変長引数の渡し方
Visual Studio 6/COM Variant配列への参照 Object[]&
Visual Stduio .NET/.NET Framework Object配列の実値 Object[]
と型が違います。Object[]の後の&の有無の違い。この一文字の有無で動作しないのだから、プログラムは難しいって逃げられるんだよな。.NET FrameworkとCOMの相互運用なんて難しそうなこと実現してるのだから、これぐらい何とかしてよ(つд`) > MS

呼ばれる側のMSScriptControlはバイナリでいじれないので、呼ぶ側がObject[]&型で引数を用意して渡す必要があります。C#ではrefを前に付ければObject[]&型を渡せるLink ようですが・・・VB.NETでどうやるんだろ、これ?

調べてもVB.NETで実現方法がわからなかったので、C#で以下のようなMSScriptControlを扱うクラスを作って対処することになりました。う〜ん、[oneway]のためだけにC#が必要Link とか、凝った事するとなるとC#なんでしょうか・・・
using System;
using System.Collections.Generic;
using System.Text;

namespace MSScriptControlInterface
{
    public class ScriptControlInterface
    {
        protected MSScriptControl.ScriptControl mScriptControlInstance;

        public ScriptControlInterface()
        {
            //
            // TODO: Add constructor logic here
            //
            mScriptControlInstance = new MSScriptControl.ScriptControl();
            mScriptControlInstance.Language = "VBScript";
        }

        ~ ScriptControlInterface()
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(mScriptControlInstance);
        }

        public void AddCode(String code)
        {
            mScriptControlInstance.AddCode(code);
        }

        public object Run(string name, object[] arguments)
        {
            return mScriptControlInstance.Run(name, ref arguments);
        }
    }
}
VB.NETだけでやる方法もあります。
  1. AddCode()で定義する関数は
    • 引数を取らないようにする
    • 次のステップで渡すグローバル変数から引数を受け取る
  2. 渡したい値はAddObject()でグローバル変数として入れておく
  3. Eval()で関数を呼び、結果を受け取る (Eval("f()")など)
引数を取る関数を定義してEval("f(5,2)")のように式に引数を書き込めばAddObjectは不要ですが、変数やオブジェクトは渡せなくなります。

今週このネタ解決するだけで終わった orz

[参考]
  1. VB 6プログラマーのためのVB.NET入門 第11回 (@IT)Link
  2. Visual Studio .NET 2003 C#、Excel COM 操作Link
  3. C#からVBS経由でExcel操作Link
  4. COM オブジェクトの参照カウントを解放する (C#, VB.NET入門)Link

— posted by mu at 05:52 pm   commentComment [0]  pingTrackBack [0]

VBScriptで正規表現

blog20070913-VB6RefVBScriptRegExp

うわ、知らなかった。VBScriptで正規表現処理するVBScript.RegExpクラスなんてあったんだ。てっきり.NET Frameworkにしか無いと勘違いしてた。これ知ってれば、いくつかのVB6プログラムで仕様変更やあの手この手で代替処理しなくてもよかったのに orz

と恥をさらす記事でしたw

[参考]

— posted by mu at 11:18 am   commentComment [0]  pingTrackBack [0]

PowerShell、どうも思っていたのと違う・・・

先日Link の続き。

流れは以下のようになるはず
  1. RunspaceConfigurationインスタンスに関数を登録
  2. そのインスタンスを引数にRunspaceFactory.CreateRunspace()でRunspaceインスタンスを生成
  3. Runspace.Open()
  4. Runspace.CreatePipeline()で関数を呼ぶ
  5. このPipelineインスタンスにCommands.Add()メソッドでコマンドを入れる
  6. PipelineインスタンスのInvoke()メソッドを呼んで実行
  7. RunspaceインスタンスのClosePipeline()を呼んで終了
が、動かない^^;

まずRunspaceConfigurationインスタンスに関数を登録する方法が不明。とりあえずこれは棚上げにして、引数なしでRunspaces.RunspaceConfiguration.Create()を呼び、インスタンスを生成。

次にPipeline.Commands.Add()メソッドは、cmdletまたはcmdletをパイプで繋いだものしか受け付けてくれないこと。つまりPowerShell上で一行づつ入力する形式そのまんまですね。といってもPowerShellで関数定義するように

function add([double]$a,[double]$b){$a+$b}

なんて入れても、次のPipeline.Invoke()の時点でエラーとなり、目論見が外れる。

となると関数はPipelineを作成する前に定義されてなければいけなくなる。それができるのは棚上げにしたRunspaceConfigurationインスタンス。このインスタンスを作成するときに.psc1ファイルを指定可能。これ拡張子が似てますがPowerShellのスクリプトファイルである.ps1とは別物で、試しに上の関数addを定義するだけの.ps1ファイルを指定したら、XML形式じゃないと怒られた。

.psc1ファイルを作成するひとつの方法は、PowerShellでexport-consoleを実行すること。試しに関数addを定義後、

export-console -path .¥test

と打ち込むとこんなファイルができた。
<?xml version="1.0" encoding="utf-8"?>
<PSConsoleFile ConsoleSchemaVersion="1.0">
  <PSVersion>1.0</PSVersion>
  <PSSnapIns />
</PSConsoleFile>
うん、全く関数addの痕跡なしw このファイルを見る限り、どうやらSnapInのことしか記録してないっぽいです。

SnapInとは特殊な形式のDLLってことで正しいのでしょうか? Visual Studioでプロジェクト作って、PSSnapInを継承したクラスを作ってビルド、これでできたクラスはインストールすればcmdletとして扱われるみたいで、そうすればPipeline.Invoke()で実行できることでしょう。

しかし先日Link にも書いたとおり、やりたいのは頻繁に変更される処理だけスクリプト化して柔軟性を増やすことなので、これでは本末転倒。今までスクリプト関数として処理していたものを、cmdletのパイプ繋ぎで実現(必要ならcmdletを作る)できるように考え方を変えないといけないのでしょうね。これ以上調べている時間もなさそうなので、今回もWindows Scripting Controlを使うことになりそうです。

[参考]コマンドレットの作成方法 (C#と諸々)Link

[2009/3/2 追記] つづきLink

— posted by mu at 05:58 pm   commentComment [0]  pingTrackBack [0]

T: Y: ALL: Online:
ThemeSwitch
  • Basic
Created in 0.0269 sec.
prev
2025.10
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31