让VB Form在所选目录中准备工作环境

时间:2012-05-16 06:21:09

标签: vb.net visual-studio-2008 embedded-resource

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

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

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

有人可以向我解释如何将.inp和.exe文件解压缩到正确的目录中吗?我在谷歌上搜索过,尝过File.WriteAllBytesFilestream.WriteByte,但没有得到理想的结果。

File.WriteAllBytes的问题是我无法指向嵌入式资源(“Simulation.exe不是资源的成员”,而Filestream.WriteByte我得到了一个0 kb的文件。

1 个答案:

答案 0 :(得分:2)

问题评论者是正确的,这可能是安装程序最好的任务。但是,已经说过,为了回答问题,我提出了以下方法。

与您的问题评论中的假设相反,您需要从GUI的可执行文件中“读取”嵌入资源,因为它是嵌入式资源而不是外部资源。它不会从可执行文件中神奇地提取itselt。您需要从组件中进行手动读取并写入指定的位置。为此,您需要使用.Net Reflection通过当前正在执行的程序集的GetManifestResourceStream方法读取资源。

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时都不会发生这种情况。这是安装程序可能是正确答案的一个重要原因。