none
I need a way to identify the Win8 device my app is running

    Question

  • So I thought about using a GUID created by myself and store it on the Windows.Storage.ApplicationData.current.localSettings section. The problem is that sometimes, haven't exactly figured out when, I key I saved in the localSettings is not there. I thought I could use that storage for app specific info I'd like to save.

    Am I in the right place? Obviously not, where can I save that info wich must be persisted and found again by the app next time it fires (even if it is a newer version of it)

    Regards,


    http://bit.ly/sebagomez

    Thursday, August 16, 2012 9:16 PM

All replies

  • Thanks Rob for your answer. I will  take a look at what you posted, but I'm actually with a problem with the settings. 

    Let me show you some code.

    	function _getDeviceId() {
    		var deviceId = 'My_DeviceId_Key';
    		var settings = Windows.Storage.ApplicationData.current.roamingSettings;
    
    		var value = settings.values[deviceId];
    		if (!value) {
    			value = Utils.guidGenerator();
    			settings.values[deviceId] = value;
    		}
    
    		return value;
    	}

    When my app first run it never finds the settings. Even more strange, if I set a breakpoint in the 'value = Utils.guidGenerator()' line, I see that value is actually undefined, BUT, if I evaluate settings.values[deviceId] I do see the Guid from the previous run. It's like if the settings were not loaded yet. 

    Keep in mind my scenario. I'm developing in one machine, and when I copy the sources to another machine is that I see that behavior. If I don't change the sources, everything runs smooth every single time. Should i be waiting for the settings to load or something?

    Regards


    http://bit.ly/sebagomez

    Thursday, August 16, 2012 10:06 PM
  • Sebastian,

    If I understand you correctly this is the problem:

    The roaming settings for your application do not seem to be roaming to another machine.

    Is that correct?

    -Jeff


    Jeff Sanders (MSFT)

    Friday, August 17, 2012 1:16 PM
  • That's is kind of correct cause I'm actually on the same computer.

    Every time I get a new version of the app and copy the code to the same computer were the previous version ran, it does not find my roamingSettings (or localSettings), but if I set a breakpoint right before the settings query and the execute it the settings are found. It's like there's a delay or something.

    Please let me know if you need further info. I guess I could create a small repro project.


    http://bit.ly/sebagomez

    Friday, August 17, 2012 3:40 PM
  • When you re-install the app it will clear the settings.  This is by design.

    When you have separate computers, you can speed up the roaming (it does not happen instantaneous) by logging out of the computer you made roaming changes to, and logging on the 2nd computer.

    -Jeff


    Jeff Sanders (MSFT)

    Friday, August 17, 2012 3:46 PM
  • Please understand I'm not re-installing the app.

    I'm just copying newer source code files to the project and pressing F5, and as I mentioned earlier, if I wait a little bit the roaming setting are there with all my values. I think I have to wait for some event to make sure the setting were loaded. I might be asking for them too soon. (?)


    http://bit.ly/sebagomez

    Friday, August 17, 2012 5:10 PM
  • You are re-installing the app.  When you hit F5 it re-deploys the application.  Don't run in the debugger the first and second time and it should all work fine!


    Jeff Sanders (MSFT)


    Friday, August 17, 2012 5:21 PM
  • Ok, I understand what you're saying but please take a look at this repro project I've put together and follow these steps:

    1) the run the app, and you'll see no settings are found (correct).

    2) Close it and run it again and you'll see the previously set settings.

    3) Go to the project folder and delete both bin and bld folders and run the app again. I guess this would be like reinstalling it, right?

    On setp 3 you'll see that the settings are not found, but if I wait for 5 seconds, settings are loading. 

    So, my guest is since I'm working with roaming settings they are being transferred to the cloud and then something is getting them back, and I guess it takes a little less than 5 seconds to get to my computer, am I right? If all that is true, is there an event or something I can wait on in order to get my settings every time?

    Thanks again for your help

    http://bit.ly/sebagomez

    Friday, August 17, 2012 10:14 PM
  • Just in case anyone else is looking for the answer, this is how I solved the Win8 device id. 

        var _internalId = '';
        function _getDeviceId() {

            if (_internalId.length == 0) {
                var packageSpecificToken = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null);
                var hardwareId = packageSpecificToken.id;
                //var signature = packageSpecificToken.signature;
                //var certificate = packageSpecificToken.certificate;

                var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(hardwareId);
                var array = new Array(hardwareId.length);
                dataReader.readBytes(array);

                for (var i = 0; i < array.length; i++) {
                    _internalId += array[i].toString();
                }
            }

            return _internalId;
        }

    This was not present in Release Preview.

    Sample taken from: http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.profile.hardwareidentification.aspx

    http://bit.ly/sebagomez

    Friday, August 17, 2012 10:24 PM
  • This code will give you a unique id for your device, but not one unique id.

    The problem with this code is that it will change if you change something with your computer.
    So if you plug in a USB mouse/keyboard it will create a different id.

    So if you're looking for a unique key you got it, but you can't use it to uniquely identify a computer.

    - Martin

    • Proposed as answer by Adam Gross Wednesday, December 19, 2012 9:33 PM
    • Unproposed as answer by Adam Gross Wednesday, December 19, 2012 9:33 PM
    Wednesday, August 22, 2012 12:28 PM
  • Thanks Martin, I guess that's not what I'm looking for :(

    Can you think of any other way to do that?


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 4:31 AM
  • Hold on Sebastian...

    Why are you storing your value in the roaming settings if you want a value unique to that machine?  What exactly are you trying to accomplish with this data?

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, August 23, 2012 12:30 PM
  • I tryied with the localSettings with the same luck :(

    I have a 'kinda' multi tenant app, but I don't want to ask my users to login in my app. So I'm using a unique identifier to ask the server for that device's data. I add that guid in every request's header and the server send back data related to my query and the guid I sent.

    Does that sound good? is there a better way to get a unique device identifier that will remain the same no matter what? can I get the mac address of the device?

    Thanks for your help!

    Edit:Actually with localSettings I never get the guid back once the app is re-installed as you mentioned. When I use roamingSettings I do find the stored guid, if I wait for 5 seconds after the app is ready.


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 4:29 PM
  • So it sounds like you need it only once.  I would use the HardwareID above!


    Jeff Sanders (MSFT)

    Thursday, August 23, 2012 4:47 PM
  • Nop, not only once. Keep in mind I send it to every server request. As mentioned above, HardwareID can change if the user plugs in a USB keyboard. And if he does, his data will not be returned by the server.

    Edit: Have you checked the repro project I attached before? 


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 6:11 PM
  • Check for the ID in roaming.

    If it does not exist, request the HardwareID and store it in Roaming. 

    Send the ID.


    Jeff Sanders (MSFT)

    Thursday, August 23, 2012 6:35 PM
  • That's the whole problem! 'Check for the ID in roaming', that is not there for at least 5 seconds after the app starts.

    Please see the repro project and you'll undertand what I mean. If I comment out the _sleep line the app does not find the ID. If I wait for 5 seconds the app does find the stored ID.


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 6:46 PM
  • I am sorry,

    I meant the local storage.  Your user is not going to be uninstalling the app and reinstalling it (except if they upgrade).  You can handle that differently.

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, August 23, 2012 6:48 PM
  • I know it works with no problems when the app is the same. The thing is, I need to solve the upgrade issue.

    Imagine my users have saved data in my servers, whenever I deploy a new version they cannot loose their data, and that's exactly what's happening today. I need a good secure way of storing an ID and get it back whenever I want, from where ever I want. 

    Could I save a file with the GUID inside? will I be able to get that file back with a newer a version of my app? can I use localStorage for that?

    Thanks a lot for your patience :)


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 7:04 PM
  • I am here to be patient! :-)

    Are you using anything other than the generated ID for user identification?  If you were, you could simply store that ID with the user information and have the user log on or identify themselves after an upgrade.

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, August 23, 2012 7:08 PM
  • No, cause I;m not interesting (for now) on identifying the user, but the device. I want the user to feel as "anonymous" with the confidence of serving his data every time.

    I will try the file approach and will come back to you.


    http://bit.ly/sebagomez

    Thursday, August 23, 2012 8:07 PM
  • For simplicity, rather than:

    for (var i = 0; i < array.length; i++) {
        _internalId += array[i].toString();
    }

    You can simply do:

    _internalId = array.join('');

    Friday, November 09, 2012 7:29 PM
  • Another way to encode the string is just to use Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String on the hardware id returned.  I tried using convertBinaryToString with UTF8 encoding but that threw an exception because the data doesn't seem to represent UTF8 data in the first place.
    Wednesday, December 19, 2012 9:35 PM