关于构建行动的澄清

时间:2012-05-22 06:02:02

标签: c# wpf build embedded-resource

我有一个项目,它使用Access DB文件作为参考表。这是在工作中使用,但我在家里开发它。到目前为止,我只是在VS2010中运行调试器,然后将相关的类文件,exe等从/ bin文件夹复制到闪存驱动器,并且工作正常。但随着数据库的加入,它在发布时突然崩溃。

我知道问题是数据库文件的文件位置。最初,DB的Build Action被发送到Content。我已将其更改为Embedded Resource,据我所知,这意味着它现在将成为exe文件的一部分。

我对此是否正确?如果没有,我需要选择什么选项才能让DB成为exe的编译部分,或者其他dll之一?

1 个答案:

答案 0 :(得分:2)

如果嵌入了db文件,则无法访问它以添加/删除行等。 为什么要将构建操作更改为嵌入式资源?最好将内容设置为内容,因此db是一个单独的文件而不是exe(但仍在同一目录中),然后构建db文件的路径(即使用Application.StartupPath)。

无论如何,如果你想将它设置为嵌入式,你需要在运行时提取数据库并在使用之前将其存储在某个地方。

这是一个可以从嵌入资源中提取文件的方法(当然,您需要更改文件名,或将其作为参数传递):

private void ExtractFromAssembly()
{
    string strPath = Application.LocalUserAppDataPath + "\\MyFile.db";
    if (File.Exists(strPath)) return; // already exist, don't overwrite
    Assembly assembly = Assembly.GetExecutingAssembly();
    //In the next line you should provide NameSpace.FileName.Extension that you have embedded
    var input = assembly.GetManifestResourceStream("MyFile.db");
    var output = File.Open(strPath, FileMode.CreateNew);
    CopyStream(input, output);
    input.Dispose();
    output.Dispose();
    System.Diagnostics.Process.Start(strPath);
}

private void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    while (true)
    {
        int read = input.Read(buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write(buffer, 0, read);
    }
}

该文件将复制到用户目录中的本地应用程序路径中。它将在应用程序第一次启动时完成,因为否则每次应用程序启动时都会覆盖db文件(用exe中的干净db包覆盖)