编译 UWP 应用程序时出错:"The use of the Windows namespace is reserved."
Error compiling UWP App: "The use of the Windows namespace is reserved."
我正在为 Windows 10 创建一个使用语音 API 的 UWP 应用程序,但我在编译时遇到了一个奇怪的错误。
场景是这样的:
A PCL 项目针对 Windows 8.1(当我创建项目时,我将 Windows 10 设置为目标,但 Visual Studio 降级为 Windows 8.1,因为 "they support the same set of portable APIs") 并引用了 "Windows.Foundation.UniversalApiContract",因为它包含语音 API(Windows.Media.SpeechRecognition 和 Windows.Media.SpeechSynthesis)。
引用 PCL 项目的 UWP 应用程序。 UWP 不使用语音 API,我只在 PCL 项目上使用它。
PCL项目构建成功,但是我构建UWP项目时出现很多这样的错误"The .winmd file 'Windows.Foundation.UniversalApiContract.winmd' contains type 'XXXXX'. The use of the Windows namespace is reserved.",我认为错误是由[=43=的引用引起的] 项目。
我尝试直接从 UWP 应用程序调用语音 API,它似乎可以工作,但我不喜欢它,因为我更喜欢在其他库项目中使用应用程序逻辑,以防万一我将应用程序移植到其他平台.
我不知道该怎么办。如果 PCL 的目标是 Windows 8.1,我必须能够像在 UWP 项目中一样使用语音 API 而无需添加引用,不是吗?是否有任何解决方法可以强制 PCL 仅针对 Windows 10?我错了,我应该改用其他项目类型 PCL?
您不能在 PCL 中引用 Windows.Foundation.UniversalApiContract
。因为它是一个可移植的 class 库,所以它不能引用仅 Windows 的库。要使用 Windows API,您需要有一个 Windows 通用 Class 库或一个 Windows 通用运行时组件。
因为你想让应用程序可移植,所以你必须选择不同的依赖注入方法。
在 可移植 Class 库中应该只是与平台无关的代码。因为 Speech APIs 绝对不是平台无关的(每个 OS 都有自己的实现,每个实现都非常不同),你只需要在你的 [=62] 中有一个 接口=] 然后在您的平台项目中提供实现.
它将如何运作?
为了简单起见,假设您只想使用语音合成(对于语音识别,解决方案是类似的)。
首先你会在你的 PCL:
中创建一个 ISpeechSynthesisService
接口
public interface ISpeechSynthesisService
{
Task SynthesizeTextAsync( string text );
}
现在您将在 UWP 项目中提供一个实现:
public class WindowsSpeechSynthesisService : ISpeechSynthesisService
{
public Task SynthesizeTextAsync( string text )
{
//implementation
}
}
因为您可能想在 PCL 项目中使用该服务(例如在 ViewModel 中,您现在将受益于使用 Dependency Injection 容器。大多数 MVVM 框架都提供开箱即用的功能(Template 10、MvvmLight、MvvmCross、Prism 等)。DI 容器允许您注册给定接口的实现 并创建它们的实例。因此在您的 UWP 项目中,您可以执行以下操作:
container.RegisterType<ISpeechSynthesisService, WindowsSpeechSynthesisService>();
然后您可以直接在PCL中获取实例,例如:
var speechService = container.GetInstance<ISpeechSynthesisService>();
或者您更愿意为您的 ViewModel 或其他服务使用构造函数注入:
public MyViewModel( ISpeechSynthesisService speechService )
{
//...
}
正如我所提到的,对于大多数 MVVM 框架,您将“免费”获得这两种方法,因此您无需手动实施。
这些错误让我抓狂,因为失败的库是在我没有注意到的情况下由 VS 自动添加的。一旦我弄明白了,解决起来就很容易了。
- 删除有问题的引用(在您的情况下
Windows.Foundation.UniversalApiContract
,但不同的库也可能发生错误,例如在我的情况下 Windows.Phone.PhoneContract
)。
- 关闭Visual Studio
- 从项目目录中删除
bin
和 obj
文件夹
- 打开项目
- 执行清理
- 为您刚刚删除的库找到一个替代品(如果需要)
- 重建,你应该会找到
我正在为 Windows 10 创建一个使用语音 API 的 UWP 应用程序,但我在编译时遇到了一个奇怪的错误。
场景是这样的:
A PCL 项目针对 Windows 8.1(当我创建项目时,我将 Windows 10 设置为目标,但 Visual Studio 降级为 Windows 8.1,因为 "they support the same set of portable APIs") 并引用了 "Windows.Foundation.UniversalApiContract",因为它包含语音 API(Windows.Media.SpeechRecognition 和 Windows.Media.SpeechSynthesis)。
引用 PCL 项目的 UWP 应用程序。 UWP 不使用语音 API,我只在 PCL 项目上使用它。
PCL项目构建成功,但是我构建UWP项目时出现很多这样的错误"The .winmd file 'Windows.Foundation.UniversalApiContract.winmd' contains type 'XXXXX'. The use of the Windows namespace is reserved.",我认为错误是由[=43=的引用引起的] 项目。
我尝试直接从 UWP 应用程序调用语音 API,它似乎可以工作,但我不喜欢它,因为我更喜欢在其他库项目中使用应用程序逻辑,以防万一我将应用程序移植到其他平台.
我不知道该怎么办。如果 PCL 的目标是 Windows 8.1,我必须能够像在 UWP 项目中一样使用语音 API 而无需添加引用,不是吗?是否有任何解决方法可以强制 PCL 仅针对 Windows 10?我错了,我应该改用其他项目类型 PCL?
您不能在 PCL 中引用 Windows.Foundation.UniversalApiContract
。因为它是一个可移植的 class 库,所以它不能引用仅 Windows 的库。要使用 Windows API,您需要有一个 Windows 通用 Class 库或一个 Windows 通用运行时组件。
因为你想让应用程序可移植,所以你必须选择不同的依赖注入方法。
在 可移植 Class 库中应该只是与平台无关的代码。因为 Speech APIs 绝对不是平台无关的(每个 OS 都有自己的实现,每个实现都非常不同),你只需要在你的 [=62] 中有一个 接口=] 然后在您的平台项目中提供实现.
它将如何运作?
为了简单起见,假设您只想使用语音合成(对于语音识别,解决方案是类似的)。
首先你会在你的 PCL:
中创建一个ISpeechSynthesisService
接口
public interface ISpeechSynthesisService
{
Task SynthesizeTextAsync( string text );
}
现在您将在 UWP 项目中提供一个实现:
public class WindowsSpeechSynthesisService : ISpeechSynthesisService
{
public Task SynthesizeTextAsync( string text )
{
//implementation
}
}
因为您可能想在 PCL 项目中使用该服务(例如在 ViewModel 中,您现在将受益于使用 Dependency Injection 容器。大多数 MVVM 框架都提供开箱即用的功能(Template 10、MvvmLight、MvvmCross、Prism 等)。DI 容器允许您注册给定接口的实现 并创建它们的实例。因此在您的 UWP 项目中,您可以执行以下操作:
container.RegisterType<ISpeechSynthesisService, WindowsSpeechSynthesisService>();
然后您可以直接在PCL中获取实例,例如:
var speechService = container.GetInstance<ISpeechSynthesisService>();
或者您更愿意为您的 ViewModel 或其他服务使用构造函数注入:
public MyViewModel( ISpeechSynthesisService speechService )
{
//...
}
正如我所提到的,对于大多数 MVVM 框架,您将“免费”获得这两种方法,因此您无需手动实施。
这些错误让我抓狂,因为失败的库是在我没有注意到的情况下由 VS 自动添加的。一旦我弄明白了,解决起来就很容易了。
- 删除有问题的引用(在您的情况下
Windows.Foundation.UniversalApiContract
,但不同的库也可能发生错误,例如在我的情况下Windows.Phone.PhoneContract
)。 - 关闭Visual Studio
- 从项目目录中删除
bin
和obj
文件夹 - 打开项目
- 执行清理
- 为您刚刚删除的库找到一个替代品(如果需要)
- 重建,你应该会找到