我需要处理现有的Word 2007 addIn项目,该项目是MSVS 2008解决方案的一部分.但是,当我尝试调试addIn时,我收到以下错误消息:"您无法调试或运行此项目,因为未安装所需的Microsoft Office应用程序版本".我安装了Office 2007.
我尝试在同一个解决方案中创建一个新的Word 2007 addIn项目,我没有问题调试它.据我所知,这两个项目之间引用的所有Office程序集都是相同的.
引用的Office程序集:
Microsoft.Office.Interop.Word(c:\ Program Files(x86)\ Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Word.dll)
Microsoft.Office.Tools.Common.v9.0(c:\ Program Files(x86)\ Reference Assemblies\Microsoft\VSTO\v9.0\Microsoft.Office.Tools.Common.v9.0.dll)
Microsoft.Office.Tools.v9.0(c:\ Program Files(x86)\ Reference Assemblies\Microsoft\VSTO\v9.0\Microsoft.Office.Tools.v9.0.dll)
Microsoft.Office.Tools.Word.v9.0(c:\ Program Files(x86)\ Reference Assemblies\Microsoft\VSTO\v9.0\Microsoft.Office.Tools.Word.v9.0.dll)
Office(c:\ Program Files(x86)\ Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Office.dll)
stole c:\ Program Files(x86)\ Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office11\stdole.dll
我尝试重建,在Debug和Release配置下启动调试.什么都没有帮助.我还缺少什么可能导致调试旧项目的问题?
我正在使用Visual Studio 2008中的VSTO开发Word 2007-2010插件.在我的插件中,我需要为每个打开的word文档创建一个自定义任务窗格.基本上,我需要为每个文档创建一个任务窗格,在文档窗口中显示正确的任务窗格,在文档关闭时执行某些操作,然后删除任务窗格及其所有引用.
这是我到目前为止所做的:
任务窗格创建
我为每个新的,打开的或现有的加载文档创建一个自定义任务窗格,如下所示:
((ApplicationEvents4_Event) Application).NewDocument += CreateTaskPaneWrapper;
Application.DocumentOpen += CreateTaskPaneWrapper;
foreach (Document document in Application.Documents)
{
CreateTaskPaneWrapper(document);
}
Run Code Online (Sandbox Code Playgroud)
在CreateTaskPaneWrapper方法中,如果文档的任务窗格已存在,则检查Dictionary <Document,TaskPaneWrapper>.我这样做是因为如果我尝试打开已打开的文档,则会触发open事件.如果它不存在,我创建一个新的TaskPaneWrapper类.在其构造函数中,我创建了一个新的任务窗格,并将其添加到CustomTaskPanes集合中
Globals.ThisAddIn.CustomTaskPanes.Add(taskPane, "Title");
Run Code Online (Sandbox Code Playgroud)
根据MSDN,这将任务窗格与当前活动窗口相关联.
任务窗格关闭
Document.Close和Application.DocumentBeforeClose事件都不适合我,因为它们在用户发出关闭文档的确认之前触发.所以我在TaskPaneWrapper类中使用Microsoft.Office.Tools.Word.Document.Shutdown事件,如下所示:
_vstoDocument = document.GetVstoObject();
_vstoDocument.Shutdown += OnShutdown;
private void OnShutdown(object sender, EventArgs eventArgs)
{
Globals.ThisAddIn.CustomTaskPanes.Remove(_taskPane);
//additional shutdown logic
}
Run Code Online (Sandbox Code Playgroud)
所有这些似乎都很好用,创建了任务窗格,绑定到相应的窗口,并成功删除.但是,我仍有一个问题 - 当我启动Word时,会打开一个空白文档.如果我然后打开现有文档而不更改空白文档,则删除空白文档及其窗口,而不会触发Document.Close,Application.DocumentBeforeClose和Microsoft.Office.Tools.Word.Document.Shutdown事件.因为未调用OnShutdown并且未删除空白文档的任务窗格,所以下一个文档窗口包含两个任务窗格 - 非常新的任务窗格,以及第一个(孤立的)任务窗格.如何删除此孤立的任务窗格?访问已删除的文档或窗口引用会抛出COMException("对象已被删除").我暂时使用这个黑客:
//A property in my TaskPaneWrapper class
public bool IsWindowAlive()
{
try
{
var window = _vstoDocument.ActiveWindow;
return true;
}
catch (COMException)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
在CreateTaskPaneWrapper方法中,我检查此属性是否包含所有现有包装器,并关闭属性为false的那些包装器.当然,捕捉异常有点贵,而且这个解决方案非常糟糕,所以我想知道,有更好的解决方案吗? …
所以,我一直认为在将文件检出到工作目录时,core.autocrlf=trueGit 会替换所有LF结尾CRLF。
从Git 书:
如果您使用的是 Windows 计算机,请将其设置为 true – 这会在您检出代码时将 LF 结尾转换为 CRLF
但是,当检出具有混合行尾并core.autocrlf设置为的文件时true,我的 Git 版本会按原样检出文件。
我找到了一个非常方便的 GitHub 存储库来测试这种行为 - https://github.com/YueLinHo/TestAutoCrlf
检测结果:
LF只有结尾的文件(LF.txt)
autocrlf=false:按原样签出(所有行结尾都是LF)autocrlf=true:CRLF结账时所有行尾都更改为到目前为止一切顺利,一切都符合我的预期。现在对于混合行结尾的文件:
autocrlf=false:签出原样(的混合LF和CRLF)autocrlf=true:签出原样(的混合LF和CRLF)为什么会发生这种情况?我没有看到任何关于autocrlf=true不接触带有混合行尾的文件的内容。
我的 Git 设置有问题吗?在全局 .gitconfig 中签出后,我检查了存储库文件夹中core.autocrlf运行的设置,命令返回 true。没有 .gitattributes 文件来覆盖设置。git config --get core.autocrlfautocrlf=true …
这是我的示例XML:
<root>
<element>
<subelement>
<value code="code1">value1</value>
<value code="code2">value2</value>
</subelement>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
这是我的测试查询:
DECLARE @tempTable TABLE (
ValueCode nvarchar(MAX),
Value nvarchar(MAX)
)
DECLARE @xml XML
select @xml = cast(c1 as xml) from OPENROWSET (BULK 'C:\test.xml', SINGLE_BLOB) as T1(c1)
INSERT INTO @tempTable
SELECT
Tbl.Col.value('subelement[1]/@code', 'NVARCHAR(MAX)'),
Tbl.Col.value('subelement[1]', 'NVARCHAR(MAX)')
FROM @xml.nodes('//element') Tbl(Col)
SELECT * FROM @tempTable
Run Code Online (Sandbox Code Playgroud)
执行时,查询会给出一行,其中ValueCode列包含NULL,而Value列包含'value1value2'.我想得到的是与分隔符连接的属性和值.例如,我需要ValueCode来包含'code1; code2'和值包含'value 1; 值2' .我怎样才能做到这一点?
在我的加载项中,我需要为每个打开的文档创建一个任务窗格。在加载项的启动方法中,我订阅了 ApplicationEvents4_Event.NewDocument 和 Application.DocumentOpen 事件,然后为每个打开的文档创建一个任务窗格:
((ApplicationEvents4_Event)Application).NewDocument += CreateTaskPaneWrapper;
Application.DocumentOpen += CreateTaskPaneWrapper;
foreach (Document document in Application.Documents)
{
CreateTaskPaneWrapper(document);
}
Run Code Online (Sandbox Code Playgroud)
这包括通过 Word 菜单打开或创建文档,或在操作系统中打开现有文档文件的情况。但是,如果 Word 已打开,则启动 WINWORD.EXE(或通过快捷方式访问它,这是一种非常常见的情况)不会触发任一事件,尽管打开了带有新文档的新窗口。我该如何应对这种情况并为以这种方式创建的文档创建任务窗格?我正在使用 VSTO 3 和 Visual Studio 2008,针对 Word 2007。
我偶然发现了一个关于哪些聚合函数适用于DATE类型列的问题(在测试中).所以,据我所知,COUNT只计算行数,MIN和MAX返回最早/最晚的日期.但是,我对SUM和AVG功能有点困惑.他们只是将DATE值转换为整数并计算这些整数的总和/平均值吗?或者我错在这里?无论如何,这种行为在SQL的所有实现中是否一致?提前致谢.
我手头有一个应用程序,它使用 FileHelpers 库来处理 csv 文件。
过去,输入的 csv 文件总是具有相同的结构,一个记录有 5 个逗号分隔的字段,然后是一个新行来分隔记录。
然而,最近我开始接收每行超过 5 条记录的 csv 文件,显然,当前用于 csv 解析的类不适用于这些行。问题是,我仍然只需要前五个字段,它们仍然以相同的顺序提供。
有没有办法用 FileHelpers 读取前五个字段,并忽略任何其他数据直到换行?
当前用于解析的类:
[IgnoreEmptyLines()]
[DelimitedRecord(";")]
public sealed class SemicolonsRow
{
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String LastName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String Name;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String MidName;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String BirthDate;
[FieldOptional()]
[FieldQuoted('"', QuoteMode.OptionalForRead, MultilineMode.AllowForRead)]
public String BirthPlace;
}
Run Code Online (Sandbox Code Playgroud) 假设我有一组“模型”实体和一组难度级别。在给定的难度级别下,每个模型在给定的一天中具有一定的成功率。
模型实体具有一个名称,该名称在任何情况下都是唯一且不可变的,因此它成为自然的主键。难度级别仅通过名称来描述(容易,正常等)。难度级别非常非常不可能改变,尽管有可能添加一个新的难度级别。成功率记录由其所属的模型,难度级别和日期唯一标识。
这是此方案中最简单的数据库设计:

在此设计中,“名称”是表“模型”的主键,并由VARCHAR(20)字段表示。同样,VARCHAR(20)字段“名称”是表“ difficulty_levels”(查找表)的主键。在“ success_rates”表中,“ model_name”是引用“ model”表中“ name”字段的外键,而“ difficulty_level”是引用“ difficulty_levels”表中“ name”字段的外键。字段“ model_name”,“ difficulty_level”和“ date”构成“ success_rates”表的复合主键。
最常用的查询是:
获取特定模型,难度级别和日期期限的所有成功率
在特定时期和难度级别获得最多/最少成功的模型。
现在,我的问题是-我需要向“模型”和“ difficulty_levels”表中添加代理主键吗?我猜想在'success_rates'的外键字段中存储int值而不是varchar值会占用较少的空间,并且查询可能会更快(只是我的疯狂猜测,不确定这一点)?
我使用代理键看到的问题是它们与业务逻辑本身的相关性为零。我正在计划使用一个迷你ORM(很可能是Dapper),并且没有代理键,我就可以在非常干净地代表我正在使用的实体的类上进行操作。现在,如果添加代理键,则必须在类中添加“ Id”属性,而我真的反对将这样的数据库存储实现添加到可在应用程序中任何位置使用的类,甚至不能在与数据库存储的连接。我可以使用Id属性添加代理存储类,但这又增加了另一层次的复杂性。加上“ Id”属性不是只读的事实(因此,ORM在将实体保存到数据库后可以设置ID)意味着可能会意外地将其设置为随机/无效值。
我对ORM不太熟悉,对Dapper的知识为零,因此,如果我在上述任何方面都不对,请更正我。
最好的方法是什么?