我有一个 Windows 窗体应用程序,我用 Word 为它写了一本内容丰富的手册,其中包含有用的图片。有没有办法将 .docx 包含在 .exe 中,以便用户可以单击应用程序中的按钮以在 Word 中打开手册?
最佳答案
我认为您的意思不是“附加”,而是“嵌入”。
是的,您可以将其存储为嵌入式资源。
在 .NET Win32 程序中可以通过三种方式嵌入资源:
- 作为 Win32 PE 资源。这不容易在 .NET 代码中使用,因为它们没有内置 API(因此您需要 P/Invoke (
DllImport
)),但这意味着其他程序可以访问资源。 - 作为直接存储的嵌入式资源流,可以使用
Assembly.GetManifestResourceStream()
访问.NET 框架中的 API。这是最快的方法(因为它显示为Stream
而不是字节数组,因此不会不必要地加载到内存中)。 - 作为
Byte[]
在 .NET 中.resx
/.resources
资源。这是次优的,因为该文件被包装在另一个抽象中并公开为Byte[]
而不是Stream
, 但您可以更轻松地在 Visual Studio 中管理文件。
我推荐 GetManifestResourceStream
方法,所以这样做:
- 在您的项目中,将 Word 文档包含在项目中(解决方案资源管理器 > 显示所有文件 >(您的文档,右键单击)> 包含文件
- 选择文件,然后打开“属性”,在“构建操作”下选择“嵌入式资源”
- 请注意,项目根目录相对文件夹路径将被转换为您的资源的点分隔名称前缀,因此如果文件是
My Project\Documents\Readme.doc
那么资源名称将是Documents.Readme.doc
. You can override this , 但您需要编辑您的.csproj
直接文件(使用<LogicalName>
元素)。 - 然后构建,你的
*.doc
文件将被嵌入。
在你的代码中,这样做:
// use a GUID generator to create a new GUID in a string literal (do not run `Guid.NewGuid()` or `new Guid()` at runtime!) to create a globally unique filename so you don't accidentally overwrite other files
const String _myFileName = "12345.doc";
static void ShellInvokeReadmeDocument() {
String destFileName = Path.Combine( Path.GetTempPath(), _myFileName );
if( !File.Exists( destFileName ) ) {
Assembly assembly = Assembly.GetExecutingAssembly(); // change as appropriate
using( Stream source = assembly.GetManifestResourceStream("Documents.Readme.doc") )
using( Stream destination = File.OpenWrite( destFileName ) ) {
source.CopyTo( destination );
}
}
Process.Start( destFileName );
}
请注意,我不建议使用 .doc
或 .docx
文件,因为不能保证用户会安装 Word(除非您知道您的客户会安装它)。
请注意,Windows 中的写字板不一定能够打开 .doc
文件!在 Windows 7 及更高版本上,写字板仅打开 .docx
文件,不支持所有格式设置选项,只有一小部分,Windows Vista 和更早版本上的写字板不支持打开 .docx
文件。
如果你想最大化兼容性,我推荐使用.pdf
文件,如果你想保留打印页面的格式和布局,或者 .rtf
文件。
如果此文件旨在构成帮助或文档文件,那么您应该使用 .chm
文件代替,它是结构化的,并且从 Windows 98 开始的所有 Windows 版本都完全支持 - 您还可以集成 .chm
带有“这是什么?”的 WinForms 文件按钮和工具提示(.chm
文件不要与 Windows Vista 之后的 Windows 不支持的 .hlp
文件混淆)。
关于c# - 我可以将 Word 文档附加到 Windows 应用程序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41577829/