VisualStudio2010のVisualBasicで質問です。自己をビルドした日時をVB上から取得できる方法を教えて下さい。

 
ルール1.自分自身のファイルスタンプを取得して、ビルドした日時とするのは無しです。
ルール2.但しsigntool.exeを使用して埋めこまれた自己の証明書タイムスタンプを読み取って取得するのは有りです。
ルール3..NET FrameworkのAPIを使用するのは有りです。但しその際は必要なバージョンを教えて頂ければ助かります。
 
以上よろしくおねがいします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/03/19 23:24:48
  • 終了:2012/03/20 14:13:52

ベストアンサー

id:cx20 No.2

cx20回答回数604ベストアンサー獲得回数1072012/03/20 00:56:17

ポイント300pt

ベタな方法ですが、IMAGE_FILE_HEADER の TimeDateStamp 項目を参照することで、コンパイル時の時間が取得できるようです。

■ Coding Horror: Determining Build Date the hard way
http://www.codinghorror.com/blog/2005/04/determining-build-date-the-hard-way.html

' File : BuildDateTest.vb
Imports System.IO
Imports System.Reflection

Module Module1
    Sub Main()
        Dim strPath = Assembly.GetExecutingAssembly().Location
        Console.WriteLine(RetrieveLinkerTimestamp(strPath))
    End Sub

    Function RetrieveLinkerTimestamp(ByVal filePath As String) As DateTime
        Const PeHeaderOffset As Integer = 60
        Const LinkerTimestampOffset As Integer = 8

        Dim b(2047) As Byte
        Dim s As Stream
        Try
            s = New FileStream(filePath, FileMode.Open, FileAccess.Read)
            s.Read(b, 0, 2048)
        Finally
            If Not s Is Nothing Then s.Close()
        End Try

        Dim i As Integer = BitConverter.ToInt32(b, PeHeaderOffset)

        Dim SecondsSince1970 As Integer = BitConverter.ToInt32(b, i + LinkerTimestampOffset)
        Dim dt As New DateTime(1970, 1, 1, 0, 0, 0)
        dt = dt.AddSeconds(SecondsSince1970)
        dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours)
        Return dt
    End Function
End Module

<参考情報>
■ EXEファイルの内部構造(PEヘッダ)(1/3):CodeZine
http://codezine.jp/article/detail/412
■ VBScript で PE ヘッダを読み込む方法 - CX's VBScript Diary - VBScript グループ
http://vbscript.g.hatena.ne.jp/cx20/20090813/1250152142

id:halohalolin

cx20さんありがとうございます。
 
試してみたところうまく行きました。助かりました。
 
余談ですが、「If Not s Is Nothing Then s.Close()」について
手持ちの環境では「変数's'は、値が割り当てられる前に使用されています。Null参照の例外が実行時に発生する可能性があります。」と注意されました。
そこで、Dim s As Stream = Nothing として使用しようと考えています。

2012/03/20 14:16:46
id:cx20

警告見落としてました。ご指摘ありがとうございます。
(コピペしてビルドが通ったので、ちゃんと確認してませんでした(汗))
「Nothing で初期化」で良いと思います。

2012/03/20 23:21:05

その他の回答(1件)

id:yossiy7 No.1

勇者よっしー回答回数778ベストアンサー獲得回数962012/03/20 00:11:27

__TIME__
で一発で取れますよ
__DATE__
で、ファイル別のコンパイル時間も取れます

id:halohalolin

Dim strDate As String = __DATE__
 
としたところ、「'__DATE__'は宣言されていません。アクセスできない保護レベルになっています。」と表示され、うまくいきません。
__DATE__ってC系のみのマクロでは無いですよね?

2012/03/20 10:48:49
id:cx20 No.2

cx20回答回数604ベストアンサー獲得回数1072012/03/20 00:56:17ここでベストアンサー

ポイント300pt

ベタな方法ですが、IMAGE_FILE_HEADER の TimeDateStamp 項目を参照することで、コンパイル時の時間が取得できるようです。

■ Coding Horror: Determining Build Date the hard way
http://www.codinghorror.com/blog/2005/04/determining-build-date-the-hard-way.html

' File : BuildDateTest.vb
Imports System.IO
Imports System.Reflection

Module Module1
    Sub Main()
        Dim strPath = Assembly.GetExecutingAssembly().Location
        Console.WriteLine(RetrieveLinkerTimestamp(strPath))
    End Sub

    Function RetrieveLinkerTimestamp(ByVal filePath As String) As DateTime
        Const PeHeaderOffset As Integer = 60
        Const LinkerTimestampOffset As Integer = 8

        Dim b(2047) As Byte
        Dim s As Stream
        Try
            s = New FileStream(filePath, FileMode.Open, FileAccess.Read)
            s.Read(b, 0, 2048)
        Finally
            If Not s Is Nothing Then s.Close()
        End Try

        Dim i As Integer = BitConverter.ToInt32(b, PeHeaderOffset)

        Dim SecondsSince1970 As Integer = BitConverter.ToInt32(b, i + LinkerTimestampOffset)
        Dim dt As New DateTime(1970, 1, 1, 0, 0, 0)
        dt = dt.AddSeconds(SecondsSince1970)
        dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours)
        Return dt
    End Function
End Module

<参考情報>
■ EXEファイルの内部構造(PEヘッダ)(1/3):CodeZine
http://codezine.jp/article/detail/412
■ VBScript で PE ヘッダを読み込む方法 - CX's VBScript Diary - VBScript グループ
http://vbscript.g.hatena.ne.jp/cx20/20090813/1250152142

id:halohalolin

cx20さんありがとうございます。
 
試してみたところうまく行きました。助かりました。
 
余談ですが、「If Not s Is Nothing Then s.Close()」について
手持ちの環境では「変数's'は、値が割り当てられる前に使用されています。Null参照の例外が実行時に発生する可能性があります。」と注意されました。
そこで、Dim s As Stream = Nothing として使用しようと考えています。

2012/03/20 14:16:46
id:cx20

警告見落としてました。ご指摘ありがとうございます。
(コピペしてビルドが通ったので、ちゃんと確認してませんでした(汗))
「Nothing で初期化」で良いと思います。

2012/03/20 23:21:05

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません