如何在C#和自动化II中设置Word文档的文件名而不保存它

7

我在这里提出了一个关于如何通过自动化设置Word文档文件名而不保存的问题。感谢Remou,我已经学会了一种通过调用FileSummaryInfo-Dialog并设置Title属性来实现此操作的好方法。

然而,我现在遇到的问题是,客户想要在文档名称中使用特殊字符(点和下划线),但似乎Word存在一个bug(或特性),它会截取标题,并仅取第一个特殊字符之前的字符来构建文件名!我已经搜索了很多,但无法找到解决这个问题的方法。这个问题也在这里(参见Gotcha下方)被注意到,但没有解决办法。

有没有其他解决方法可以设置文件名而不保存,或者针对上述奇怪的行为的解决方法/临时方法?


你说的是什么意思,点和下划线? - paparazzo
@Blam: "." 和 "_"。例如"My_Document_2012_11_29"或"My_Document_2012.11.29"。这两个文档的名称都将是"My.doc"。您也可以在没有自动化的情况下测试行为:创建一个新的空白文档,将文档标题(在文档属性对话框中)设置为上述任一标题,然后按Ctrl-S。 - HCL
2
这是内置的Word行为,你无法对其进行黑客攻击。请注意,任何标点符号(包括破折号、斜线或逗号)都会截断它,但空格不会。你只是看到Word试图从长标题中合成一个短文件名。此外,在这里也有相关信息:http://www.microsoft-word-answers.com/microsoft/Word-VBA/33441907/default-suggested-filename.aspx - Hans Passant
@Hans Passant:这是个令人沮丧的消息。然而,我本以为会是这样,但希望总是最后消失的... - HCL
还要注意,如果您没有设置标题,则它会尝试从文档中的第一段合成文件名。不过行为完全相同。 - Hans Passant
1个回答

5

请尝试使用easyhook,因为我手边除了Windows机器之外没有其他设备。

以下只是调用流程(类似于我多年前所做的事情,通过Detours将软件的套接字绑定端口更改为不同的端口)

关于Hook the CreateFileW:

easyhook维基中的示例正是我们想要的。

CreateFileHook = LocalHook.Create(
                    LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"),
                    new DCreateFile(CreateFile_Hooked),
                    this);

CreateFile_Hooked函数中,您可以更改参数InFileName,然后调用真正的CreateFileW函数。
static IntPtr CreateFile_Hooked(
    String InFileName,
    UInt32 InDesiredAccess,
    UInt32 InShareMode,
    IntPtr InSecurityAttributes,
    UInt32 InCreationDisposition,
    UInt32 InFlagsAndAttributes,
    IntPtr InTemplateFile)
{
    // FIGURE OUT THE FILE NAME THAT YOU WANT HERE
    // IF the InFileName is not your Document name "My.doc", then call orignal CreateFile
    // with all the parameter unchanged.

    // call original API...
    return CreateFile(
        YOUR_CHANGED_FILE_NAME_HERE,
        InDesiredAccess,
        InShareMode,
        InSecurityAttributes,
        InCreationDisposition,
        InFlagsAndAttributes,
        InTemplateFile);
}

呼叫流程:

在您将标题更改为“My_Document_2012_11_29”之后,钩取Word进程的CreateFileW。例如,当InFileName为“My.doc”时, 则应将其更改为“My_Document_2012_11_29”。

由于这是在Word进程中完成的,因此Detoured函数不知道“My.doc”映射到“My_Document_2012_11_29”。 有很多方法可以获取此映射信息,其中一种方法是将此映射信息保存到应用程序中的已知文件中,并在Detoured函数中读取该文件。


+1 感谢您提供的创意解决方案。但是,如果我正确理解了您的解决方案的方式,那么在客户端保存文件后(单击“保存文件”对话框中的“确定”按钮),名称将会更改。这意味着在保存文件对话框中,将显示短标题(My.doc),而不是标题?然而,重要的是,在保存文件对话框中正确显示文件名。但再次感谢您提供的好的解决方案! - HCL
@HCL,是的,你说得对。也许我们需要在这里挂钩SetWindowText方法。 - whunmr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接