2012年2月9日木曜日

Optiplex GX520 内蔵電池交換

何年間か使っているDell Optiplex GX520の起動時に以下のメッセージが表示されるようになりました。

"Alert! System battery voltage is low."

内蔵電池が弱ってるんだなと判断し,電池交換することにしました。
使用した電池は以下の通り。


5個セットあってもすぐには使わないけど,CR2032はまた使うだろうからということで決定。
Prime対象で送料もかからないし,近所とはいえ量販店に行くのも時間がかかるので今回はAmazonで購入することにしました。
電池交換の手順はメーカーサイトに載っていたのでいちおう確認。

Dell™ OptiPlex™ GX520 ユーザーズガイド:バッテリー交換

筐体を開けてHDDを外すと電池が見えますので,これを交換するだけです。
HDDはワンタッチで外れるようになっていて,とても簡単です。


交換後,電源を入れると各種エラーが表示されるかもしれません。
BIOS設定が全部消えているので,F2を押して設定をするように指示が出ます。
まずは日時を合せます。次いで,PCの環境に合わせてデバイスの設定を行ないます。
今回の場合は内蔵FDDがないのでFDDのタイプをUSBに変更するなどの設定を行ないました。

これでPCからメッセージが出ることなく起動するようになりました。

2012年2月2日木曜日

ソースには,DataRowが含まれていません

Linqを使ってデータテーブルの処理をしている途中,エラーが発生してしまいました。

"System.InvalidOperationException: Linq The source contains no DataRows."
ソースには、DataRow が含まれていません。

コーディング中にエラーは出ないのですが,デバッグを始めると状況によってうまくいったりいかなかったりです。
もういちどよくエラーメッセージの意味を考えた結果,Linqで抽出した結果が0だったのが問題だったと分かりました。

Private Sub LinqToDataSet()

    Dim dt1 As New DataTable
    dt1.Columns.Add("Key")
    dt1.Columns.Add("Value")

    For i = 1 To 10
        Dim r As DataRow = dt1.NewRow
        r("Key") = "Key-" & i.ToString("00")
        r("Value") = "Value-" & i.ToString("00")
        dt1.Rows.Add(r)
    Next

    Dim searchKey As String = "Key-99"
    Dim query = dt1.AsEnumerable.Where(Function(el As DataRow) el("Key") = searchKey)
    SetDataRow(query.CopyToDataTable.Rows) 'ここでエラー発生。

End Sub

Private Sub SetDataRow(ByVal rows As DataRowCollection)

    For Each r In rows
        Debug.WriteLine(r("Key") & "|" & r("Value"))
    Next

End Sub

というわけで,結果の数を確認して処理するようにしました。

If query.Count > 0 Then SetDataRow(query.CopyToDataTable.Rows)

単純なことで手間取ってしまい,少々残念です。

2012年1月25日水曜日

Android3.1 マーケットでダウンロードが終わらない

LGのL-06C OptimusPADのAndroidマーケットで,ある日ダウンロードができなくなりました。
アプリのアップデートがあるということで開始し,プログレスバーみたいなゲージがずっと動いているのですが一向に終わることなく,結局「ダウンロードできませんでした」となる状態が続いていました。

設定 > アプリケーション > アプリケーションの管理 > すべて

この中にある「マーケット」を選択,「キャッシュを消去」を行なって再起動したけどうまくいかず。
次に「ダウンロード」 というアプリを選択,「キャッシュを消去」を実行。
この時点で直りました。

「ダウンロード」のキャッシュは数百MBたまっていましたが,これが悪かったのか,あるいは不具合でデータがたまっていたのか・・。

後日,Android2.2のT-01C(Regza Phone)でも同様の状況が発生。そして同様の処置で問題解決しました。

2012年1月23日月曜日

お年玉つき年賀葉書の当選番号照合

今年も年賀葉書の当選番号が発表されました。

平成24年用年賀葉書及び寄附金付お年玉付年賀切手当せん番号

そこで,弊社総務部用に照合シートを作成しました。
ただIF文を繰り返すだけの関数ですが,たくさん葉書がある場合は便利です。


年賀葉書当せん番号照合シート_2011.xlsx

2012年1月13日金曜日

WCF+RESTでファイル受信する際にヘッダー情報を分離

ASP.NETでWCFをホストし,POSTメソッドでファイルを受信するのはうまくできたのですが,受信した Stream型(System.IO.Stream)にヘッダー情報が含まれてしまい,そのまま保存するとファイルが壊れてしまうという問題に当たってしまいました。


FiddlerでファイルをPOST送信したときのRequestBody

---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="test.JPG"
Content-Type: image/jpeg

<@INCLUDE *C:\Users\nemo\Pictures\test.JPG*@>
---------------------------acebdf13572468--

.NETのライブラリに便利なものはないかいろいろと調べたけれど見つからず,結局コードを書いて処理しなくてはいけないかと考えましたが,幸い以下のコードが公開されていました。

http://multipartparser.codeplex.com/

VBで使えるように変換・調整して使うと,簡単に解決しました。

変換サイト

VB.NET(修正前)

' Get the start & end indexes of the file contents
Dim startIndex As Integer = contentTypeMatch.Index + contentTypeMatch.Length + vbCr & vbLf & vbCr & vbLf.Length

Dim delimiterBytes As Byte() = encoding.GetBytes(vbCr & vbLf & delimiter)

VB.NET(修正後)

' Get the start & end indexes of the file contents
Dim startIndex As Integer = contentTypeMatch.Index + contentTypeMatch.Length + vbCr.Length + vbLf.Length + vbCr.Length + vbLf.Length

Dim delimiterBytes As Byte() = encoding.GetBytes(vbCr & vbLf & delimiter)

ファイル名の取得もプロパティでできるし,快適です。
開発者に感謝です。

2012年1月10日火曜日

Windows AzureでIPアドレスによるアクセス制限をかける

Windows AzureのWeb RoleでIPアドレスによるアクセス制限をかける必要が生じ,調べてみました。TIPSやブログを読むと,SQL Azureの場合は管理画面で簡単に設定できるのですが,Web Roleの場合はIISをベースに動いているのでインスタンスごとに初期設定を行なわなければいけないということでした。リモートデスクトップで接続してGUIで設定することもできますが,インスタンスを作成する度に最初からやり直しなので,自動で再構成したときのことも考えると実用的ではありません。
設定を自動的に行なう具体的な方法についてはいくつかのやり方があるようですが,自分にとっては以下の手順が簡単に思えたので記録しておくことにします。


状況
許可したIPアドレスからのアクセス以外を制限
127.0.0.1 WebRoleがlocalhostにアクセスする場合に許可
192.168.1.1 からのアクセスを許可

1.StartUp.cmd
WebRoleプロジェクトにテキストファイルとして StartUp.cmd を作成。
プロパティの[出力ディレクトリにコピー]を[常にコピーする]に設定。

以下の内容で保存。

@echo off 
%windir%\System32\ServerManagerCmd.exe -install Web-IP-Security 
%windir%\system32\inetsrv\AppCmd.exe unlock config -section:system.webServer/security/ipSecurity

2.ServiceDefinition.csdef
Windows Azureプロジェクトの ServiceDefinition.csdef に以下の内容を追記。

  <WebRole>
    <Startup>
      <Task commandLine="StartUp.cmd" executionContext="elevated" taskType="simple" />
    </Startup>
  </WebRole>

3.Web.Config
WebRoleプロジェクトの Web.Config に以下の内容を追記。

<system.webServer>
  <!--IPアドレスによるアクセス制限-->
  <security>
    <ipSecurity allowUnlisted="false">
      <clear/>
      <add ipAddress="127.0.0.1" allowed="true"/>
      <add ipAddress="192.168.1.1" allowed="true" />
    </ipSecurity>
  </security>
</system.webServer>


参考
http://news.mynavi.jp/articles/2011/06/07/wings02/index.html
https://support.blacknight.ie/524/how-to-block-an-ip-address.html

2011年12月14日水曜日

WebBrowserコントロールで要素に値を入力

WebBrowserコントロールのフォームに任意の値を自動入力する方法をメモ。
社内で使用する業務用WebアプリをWindowsアプリケーションの中で扱えないかと思い,WebBrowserコントロールを使ってみました。
アカウント認証が必要なので,アカウント情報を自動入力して送信します。

まずはテキストボックスへの入力とボタンクリックのメソッドを用意。

    ''' 
    ''' 指定のURLに接続します。
    ''' 
    ''' URL
    ''' 
    Public Sub SetUrl(ByVal url As String)

        webBrowser1.Navigate(url)

    End Sub

    ''' 
    ''' ウェブページ内のテキストボックスに文字列を入力します。
    ''' 
    ''' 要素ID
    ''' 文字列
    ''' 
    Public Sub SetStringToTextBox(ByVal elementId As String, ByVal value As String)

        Dim all As HtmlElementCollection = webBrowser1.Document.All
        Dim forms As HtmlElementCollection = all.GetElementsByName(elementId)
        If forms.Count > 0 Then
            forms(0).InnerText = value
        End If

    End Sub

    ''' 
    ''' ウェブページ内のボタンをクリックします。
    ''' 
    ''' 要素ID
    ''' 
    Public Sub ClickWebButton(ByVal elementId As String)

        Dim all As HtmlElementCollection = webBrowser1.Document.All
        Dim forms As HtmlElementCollection = all.GetElementsByName(elementId)
        If forms.Count > 0 Then
            forms(0).InvokeMember("click")
        End If

    End Sub

Webページの読み込みが完了した時点で自動入力して送信。


    Private Sub webBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles webBrowser1.DocumentCompleted

        SetStringToTextBox("Account", "myAccount")
        SetStringToTextBox("Password", "myPassword")
        ClickWebButton("Submit")

    End Sub

うまくいったのはいいけど,別ウィンドウを表示する動作で認証が途切れてしまいました。 セッションのことまで考えるとなかなか単純にはいかないようです。 別ウィンドウでのセッション維持が不要なら,使えそうです。