2

シミュレーション プログラムの GUI に取り組んでいます。File.inpシミュレーション プログラムは、入力ファイル (同じディレクトリにある)によって駆動される単一の .exe です。このOriginal.inpファイルは、フォームがすべての値を配列に読み取るテンプレートとして機能します。次に、ユーザーがフォームで行った変更を反映してこれらの値を変更します。その後、すべての新しい値を に書き込みますFile.inp。「実行」ボタンを押すと、Simulation.exeファイルが実行されます。フォルダ構造は次のようになります。

root  
|  
|---input   
|   |  
|   |--Original.inp
|
|---GUI.exe
|---Simulation.exe
|---File.inp

理想的には、GUI のみを提供し、ユーザーが作業ディレクトリを選択すると、GUI.exe が入力フォルダーを作成し、適切な場所にOriginal.inpandを抽出します。これまでのところ、VB プロジェクトに"EmbeddedResources" としてSimulation.exe含めることしかできず、ユーザーが選択した作業ディレクトリにコードで入力フォルダーを作成しました。Original.inpSimulation.exe

.inp および .exe ファイルを正しいディレクトリに抽出する方法を誰かに説明してもらえますか? 私はグーグルで検索し、試しFile.WriteAllBytesてみましFilestream.WriteByteたが、望ましい結果が得られませんでした。

問題File.WriteAllBytesは、埋め込まれたリソースを指すことができなかったことです (「Simulation.exe はリソースのメンバーではありません」でFilestream.WriteByte、0 kb のファイルを取得しました。

4

1 に答える 1

2

質問のコメント者は正しいです。これはおそらく、セットアップ プログラムに任せるのが最善の作業です。しかし、そうは言っても、尋ねられた質問に答えるために、次のアプローチを提供します。

質問のコメントでの仮定に反して、埋め込みリソースは外部リソースではなく埋め込みリソースであるため、GUI の実行可能ファイルから埋め込みリソースを「読み取る」必要があります。実行可能ファイルから魔法のようにそれ自体を抽出することはありません。アセンブリから手動で読み取り、指定した場所に書き込む必要があります。これを行うには、現在実行中のアセンブリの GetManifestResourceStream メソッドを介して、.Net Reflection を使用してリソースを読み取る必要があります。

このSimulation.exeファイルはバイナリ ファイルであるため、そのように処理する必要があります。Orginal.inpさまざまなタイプのファイルの読み取りと書き込みを実演する機会が与えられたので、ファイルはテキスト ファイルであると想定しました。簡潔にするために、すべてのエラー処理 (および多くのエラー処理があるはずです) は省略されています。

コードは次のようになります。

Imports System.IO
Imports System.Reflection

Module Module1

Sub Main()
    'Determine where the GUI executable is located and save for later use
    Dim thisAssembly As Assembly = Assembly.GetExecutingAssembly()
    Dim appFolder As String = Path.GetDirectoryName(thisAssembly.Location)

    Dim fileContents As String = String.Empty

    'Read the contents of the template file. It was assumed this is in text format so a 
    'StreamReader, adept at reading text files, was used to read the entire file into a string
    'N.B. The namespace that prefixes the file name in the next line is CRITICAL. An embedded resource
    'is placed in the executable with the namespace noted in the project file, so it must be 
    'dereferenced in the same manner.
    Using fileStream As Stream = thisAssembly.GetManifestResourceStream("SOQuestion10613051.Original.inp")
        If fileStream IsNot Nothing Then
            Using textStreamReader As New StreamReader(fileStream)
                fileContents = textStreamReader.ReadToEnd()
                textStreamReader.Close()
            End Using
            fileStream.Close()
        End If
    End Using

    'Create the "input" subfolder if it doesn't already exist
    Dim inputFolder As String = Path.Combine(appFolder, "input")
    If Not Directory.Exists(inputFolder) Then
        Directory.CreateDirectory(inputFolder)
    End If

    'Write the contents of the resource read above to the input sub-folder
    Using writer As New StreamWriter(Path.Combine(inputFolder, "Original.inp"))
        writer.Write(fileContents)
        writer.Close()
    End Using

    'Now read the simulation executable. The same namespace issues noted above still apply.
    'Since this is a binary file we use a file stream to read into a byte buffer
    Dim buffer() As Byte = Nothing
    Using fileStream As Stream = thisAssembly.GetManifestResourceStream("SOQuestion10613051.Simulation.exe")
        If fileStream IsNot Nothing Then
            ReDim buffer(fileStream.Length)
            fileStream.Read(buffer, 0, fileStream.Length)
            fileStream.Close()
        End If
    End Using

    'Now write the byte buffer with the contents of the executable file to the root folder
    If buffer IsNot Nothing Then
        Using exeStream As New FileStream(Path.Combine(appFolder, "Simulation.exe"), FileMode.Create, FileAccess.Write, FileShare.None)
            exeStream.Write(buffer, 0, buffer.Length)
            exeStream.Close()
        End Using
    End If

End Sub

End Module

また、GUI が呼び出されるたびにファイルが抽出されないように、ファイルが抽出されたかどうかを判断するロジックを追加する必要があります。これが、インストール プログラムが正解である大きな理由です。

于 2012-05-25T03:25:39.107 に答える