2

我正在为一个模拟程序开发一个 GUI。模拟程序是由输入文件驱动的单个 .exe(File.inp位于同一目录中)。该Original.inp文件用作模板,表单从中读取所有值到数组中。然后它会更改这些值,以反映用户在表单中所做的更改。之后,它将所有新值写入File.inp. 通过按下“运行”按钮,Simulation.exe文件被执行。文件夹结构如下所示:

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

理想情况下,我只提供 GUI,用户将选择工作目录,然后 GUI.exe 将创建一个输入文件夹并将 and 提取Original.inpSimulation.exe适当的位置。到目前为止,我只设法在我的 VB 项目中包含Original.inpSimulation.exe作为“EmbeddedResources”,并且我让我的代码在用户选择的工作目录中创建了一个输入文件夹。

有人可以向我解释如何将 .inp 和 .exe 文件提取到正确的目录中吗?我在谷歌上搜索过,尝试过File.WriteAllBytesFilestream.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 回答