积极答复者
关于在win32程序中调用winrt的一些Api

问题
-
我在一个win32的WPF程序中,在References中增加引用System.Runtime和Windows(就是metro下WPF中新建默认的两个引用),然后调用winrt下的相关类和Api,比如DataReader dr = new DataReader(stream.GetInputStreamAt(0));但是不能用await dr.LoadAsync((uint)stream.Size);请版主解释下。要是我自己手动编写异步代码,如:
DataReaderLoadOperation drlo = dr.LoadAsync((uint)stream.Size);
drlo.Completed = new AsyncOperationCompletedHandler<uint>(SaveToFileCompleted);是否可以,如果可以需要注意哪些情况。
我写了个获取锁屏背景图片的程序,但是不管我怎么更改锁屏背景图片,得到图片始终为同一张,附上代码如下(希望版主可以测试下):
private void getImage_Click_1(object sender, RoutedEventArgs e)
{
SaveLockScreenImage();
}private void SaveLockScreenImage()
{
using (IRandomAccessStream imageStream = Windows.System.UserProfile.LockScreen.GetImageStream())
{
SaveStreamToFile(imageStream);
}
}DataReader dr;
private void SaveStreamToFile(IRandomAccessStream stream)
{
try
{
dr = new DataReader(stream.GetInputStreamAt(0));
DataReaderLoadOperation drlo = dr.LoadAsync((uint)stream.Size);
drlo.Completed = new AsyncOperationCompletedHandler<uint>(SaveToFileCompleted);
}
catch (Exception)
{
}
}void SaveToFileCompleted(IAsyncOperation<uint> asyncInfo, AsyncStatus asyncStatus)
{
if (asyncStatus == AsyncStatus.Completed)
{
uint size = asyncInfo.GetResults();
byte[] bytesArray = new byte[size];
dr.ReadBytes(bytesArray);FileStream fs = new FileStream(fileName, FileMode.Create);
fs.Write(bytesArray, 0, bytesArray.Length);fs.Flush();
fs.Close();
dr.Dispose();}
}- 已移动 Jie Bao 2012年5月15日 10:30 (发件人:Windows 8 Metro风格应用开发)
答案
-
你好,
我先将其移出Metro论坛,这个只能说是Desktop应用来使用WinRT的API。
目前官方并没有明确表达说Desktop应用可以使用WinRT API, 但是可以确认的是,如果你是使用的WinRT API不依赖于任何Metro环境,他应该是可以被使用的。
还有,await可以被用在Desktop应用中,但是被调用的方法需要返回Task<T>类型,因为Task提供了GetAwaiter方法,但是WinRT的API,例如这里LoadAsync是返回DataReaderLoadOperation 类型,实现
IAsyncOperation<T>, IAsyncInfo
并没有提供 GetAwaiter 以供使用。
------------------
对于调试出现的那个Size的问题,因为这个值是在并行的线程才能获得,当前调试的线程是拿不到的。
------------------
至于为什么永远是同一张,那是因为 Windows.System.UserProfile 返回的用户永远是
这个空帐户,所以不是你当前的那个用户。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- 已标记为答案 Mike FengModerator 2012年5月23日 4:07
-
找到一个原因了,我们测试的时候需要设置这个 Desktop App 的 Build Target 显式为x64,
默认情况下,我们的桌面应用调用这个API的时候去读取一个 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\AccountPicture 下的 AppsReadAccess 键值,但是Wow6332Node下没有,所以我怀疑是不是系统调用API以x86形式运行了。 所以我就显式地运行我同事的例子以x64方式。在我的x64 Win 8测试好了,
AccountPictureChangeEnabled: True
NameAccessAllowed: True均为True。
之前我同事测试的环境是Win 8 x86所以他一直是好的,没有平台的问题。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- 已标记为答案 Leo06053308 2012年5月30日 8:28
全部回复
-
你好,
我先将其移出Metro论坛,这个只能说是Desktop应用来使用WinRT的API。
目前官方并没有明确表达说Desktop应用可以使用WinRT API, 但是可以确认的是,如果你是使用的WinRT API不依赖于任何Metro环境,他应该是可以被使用的。
还有,await可以被用在Desktop应用中,但是被调用的方法需要返回Task<T>类型,因为Task提供了GetAwaiter方法,但是WinRT的API,例如这里LoadAsync是返回DataReaderLoadOperation 类型,实现
IAsyncOperation<T>, IAsyncInfo
并没有提供 GetAwaiter 以供使用。
------------------
对于调试出现的那个Size的问题,因为这个值是在并行的线程才能获得,当前调试的线程是拿不到的。
------------------
至于为什么永远是同一张,那是因为 Windows.System.UserProfile 返回的用户永远是
这个空帐户,所以不是你当前的那个用户。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- 已标记为答案 Mike FengModerator 2012年5月23日 4:07
-
那怎么解决返回的图片始终是同一张的问题,要获得锁屏图片必须在metro下获得么。
但是用SetImageStreamAsync可以设置锁屏背景图片,切换到锁屏时,相应的背景图片也会改变。这不是矛盾么,不能获取,却可以设置
- 已编辑 Leo06053308 2012年5月16日 8:34
-
要使用WinRT的API,目前官方也没有详细的说明那些是可行的,那些不可以。现在能确定的只是如果他不依赖于Metro环境,则可以。但是就你测试的结果看,获取的API需要Metro的环境,虽然他可以返回一些值,但不是我们所期望的。
不矛盾,我们并不了解其内部的实现,如果能知道其实现,应该可以解释。 但是目前这些资料都是非公开的,不好进行更深入的研究。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
-
嗯,所以这个类是可以在Desktop App使用的, 但是没有达到预期效果, 目前不清楚其内部逻辑, 没有更详细的说明在此了。我去咨询下,但是我估计详细的内容还是要等有版本更新才能知道了。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
-
- 已编辑 Leo06053308 2012年5月28日 3:28
-
我联系了我的同事Mike Dos Zhang 关于他回复的那个帖子, 它给出例子代码是Desktop App Windows Form的,并不是Metro 的。他的例子是相应通过 API SetImageStreamAsync 去设置图片,然后GetImageStream; 或者 SetImageFileAsync 然后 Windows.System.UserProfile.LockScreen.OriginalImageFile.AbsolutePath 去Get,是可以的。要一一对应,前者规定,只有当前App设置的图片才可以被当前App获得;后者规定,只有OriginalImageFile 有的时候才可以Get。
//GetImageStream Remarks: http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.userprofile.lockscreen.getimagestream.aspx
//This method can be called only by apps that have set the "Picture Library Access" capability in the package manifest
//**or bythe app that set this image on the lock screen.
//This property retrieves only files.
//**If the image was set through a stream, this call will return E_FILE_NOT_FOUND.Bob Bao [MSFT]
MSDN Community Support | Feedback to us
-
我试过他的例子,设置的时候都不成功。很奇怪的现象,在PC seetings里面显示锁屏背景已经改变,但是WIN+L切换到锁屏时发现背景图片还是上此的图片
- 已编辑 Leo06053308 2012年5月28日 7:05
-
找到一个原因了,我们测试的时候需要设置这个 Desktop App 的 Build Target 显式为x64,
默认情况下,我们的桌面应用调用这个API的时候去读取一个 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\AccountPicture 下的 AppsReadAccess 键值,但是Wow6332Node下没有,所以我怀疑是不是系统调用API以x86形式运行了。 所以我就显式地运行我同事的例子以x64方式。在我的x64 Win 8测试好了,
AccountPictureChangeEnabled: True
NameAccessAllowed: True均为True。
之前我同事测试的环境是Win 8 x86所以他一直是好的,没有平台的问题。
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
- 已标记为答案 Leo06053308 2012年5月30日 8:28
-
非常感谢,我试下了,现在可以取到了
以X64的方式又是怎么样的一个过程呢?和X86方式又什么不同- 已编辑 Leo06053308 2012年5月30日 8:40