none
How to use the ProtectedData class from a Winodws service RRS feed

  • Question

  • I'm trying to use the ProtectedData class from a Windows Service, using the "CurrentUser" scope. It fails with the error "Key not valid for use in specified state.". I believe this is because the user profile is not loaded. How can I load the user profile for the service account running the service?


    Hallis

    Monday, May 12, 2014 6:43 AM

Answers

  • Hi Hallis,

    The LoadUserProfile method need administrator privileges. Please run the application as administrator.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by Hallis Thursday, May 22, 2014 8:55 AM
    Thursday, May 22, 2014 8:50 AM
    Moderator

All replies

  • If your service is visible for any user, then you probably can use LocalMachine scope.

    Monday, May 12, 2014 11:20 AM
  • The service processes data from another server. A "front end" webservice stores encrypted data in a database. This windows service decrypts the data and processes it. Both the front end and back end services runs as the same domain user.

    For services hosted in IIS there is a "Load User Profile" option. Is there a similar thing for Windows services?


    Hallis

    Monday, May 12, 2014 11:27 AM
  • Hi Hallis,

    Have a look at the code on the following link. Try it and let me know the result.

    http://dotbay.blogspot.jp/2009/05/loading-user-profile-from-c.html.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, May 15, 2014 7:55 AM
    Moderator
  • The code on your link show how do do impersonation. That is not the case with my code. I want to load the user profile of the current user (the service account that runs the service).

    Hallis

    Monday, May 19, 2014 9:37 AM
  • Hi Hallis,

    WindowsIdentity.GetCurrent method can represent the current windows user. Read more information from http://msdn.microsoft.com/en-us/library/sfs49sw0.aspx. Please try and then let me know the result.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, May 20, 2014 9:39 AM
    Moderator
  • I have made a small command line program based on various sources on the internet to test the code, but i get an error:

    LoadUserProfile() failed with error code: 1314
    
    Unhandled Exception: System.ComponentModel.Win32Exception: A required privilege is not held by the client.
    

    The code:

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
    
    namespace Test
    {
      class Program
      {
        [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);
    
        static void Main(string[] args)
        {
          IntPtr hToken;
          string username;
          ProfileInfo profileInfo;
          bool success;
    
          hToken = WindowsIdentity.GetCurrent().Token;
          username = WindowsIdentity.GetCurrent().Name;
    
          username = username.Substring(username.IndexOf('\\') + 1);
    
    
          profileInfo = new ProfileInfo();
          profileInfo.lpUserName = username;
          profileInfo.dwFlags = 1;
          profileInfo.dwSize = Marshal.SizeOf(profileInfo);
    
          
    
          Console.WriteLine("Username: " + username);
          Console.WriteLine("Token   : " + hToken.ToString());
    
    
          success = LoadUserProfile(hToken, ref profileInfo);
    
          if (!success)
          {
            Console.WriteLine("LoadUserProfile() failed with error code: " + Marshal.GetLastWin32Error());
            throw new Win32Exception(Marshal.GetLastWin32Error());
          }
    
          if (profileInfo.hProfile == IntPtr.Zero)
          {
            Console.WriteLine("LoadUserProfile() failed - HKCU handle was not loaded. Error code: " + Marshal.GetLastWin32Error());
            throw new Win32Exception(Marshal.GetLastWin32Error());
          }
        }
      }
    
      [StructLayout(LayoutKind.Sequential)]
      public struct ProfileInfo
      {
        public int dwSize;
        public int dwFlags;
        public string lpUserName;
        public string lpProfilePath;
        public string lpDefaultPath;
        public string lpServerName;
        public string lpPolicyPath;
        public IntPtr hProfile;
      }
    }
    


    Hallis

    Wednesday, May 21, 2014 12:47 PM
  • Hi Hallis,

    The LoadUserProfile method need administrator privileges. Please run the application as administrator.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by Hallis Thursday, May 22, 2014 8:55 AM
    Thursday, May 22, 2014 8:50 AM
    Moderator
  • It works with admin privileges, however that will not work in the real world. I guess there is no way for a service to accces its user profile. I'll implement key management myself.

    Hallis

    Thursday, May 22, 2014 8:58 AM