none
关于在win32程序中调用winrt的一些Api RRS feed

  • 问题

  • 我在一个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风格应用开发)
    2012年5月11日 6:42

答案

  • 你好,

    我先将其移出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

    2012年5月15日 10:30
  • 找到一个原因了,我们测试的时候需要设置这个 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

    2012年5月29日 9:36

全部回复

  • 调试的时候出现这个情况,见图:

    2012年5月11日 9:10
  • 你好,

    我先将其移出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

    2012年5月15日 10:30
  • 那怎么解决返回的图片始终是同一张的问题,要获得锁屏图片必须在metro下获得么。

    但是用SetImageStreamAsync可以设置锁屏背景图片,切换到锁屏时,相应的背景图片也会改变。这不是矛盾么,不能获取,却可以设置


    2012年5月16日 7:56
  • 要使用WinRT的API,目前官方也没有详细的说明那些是可行的,那些不可以。现在能确定的只是如果他不依赖于Metro环境,则可以。但是就你测试的结果看,获取的API需要Metro的环境,虽然他可以返回一些值,但不是我们所期望的。

    不矛盾,我们并不了解其内部的实现,如果能知道其实现,应该可以解释。 但是目前这些资料都是非公开的,不好进行更深入的研究。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年5月17日 6:44
  • MSDN上说明“LockScreen”类可以应用与Desktop App和Metro App
    2012年5月17日 7:18
  • 嗯,所以这个类是可以在Desktop App使用的, 但是没有达到预期效果, 目前不清楚其内部逻辑, 没有更详细的说明在此了。我去咨询下,但是我估计详细的内容还是要等有版本更新才能知道了。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年5月17日 7:43
  • 好的,谢谢了。不过我试过在RC版本也是不行的

    2012年5月17日 8:59
  • 2012年5月28日 3:16
  • 我联系了我的同事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.

                //OriginalImageFile Remarks: http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.userprofile.lockscreen.originalimagefile
                //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

    2012年5月28日 3:59
  • 我试过他的例子,设置的时候都不成功。很奇怪的现象,在PC seetings里面显示锁屏背景已经改变,但是WIN+L切换到锁屏时发现背景图片还是上此的图片


    2012年5月28日 6:51
  • 找到一个原因了,我们测试的时候需要设置这个 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

    2012年5月29日 9:36
  • 非常感谢,我试下了,现在可以取到了
    以X64的方式又是怎么样的一个过程呢?和X86方式又什么不同
    2012年5月30日 8:26
  • 请版主在RP版本下再测试下看看,貌似又有问题
    2012年6月18日 7:33
  • “我写了个获取锁屏背景图片的程序,但是不管我怎么更改锁屏背景图片,得到图片始终为同一张”,你能否展示一下更改锁屏背景图片的代码吗?
    2012年11月20日 10:56