0

I'm writing a Windows service in C#. The service will write a TXT file in the user's My Documents folder. Because every user will obviously have a different name, I'm using the methods in the documentation to get it. However, it's returning an empty string.

My insight so far from searching through SO is that it's because this service is running as system instead of user, which I intend for it to do. But how then can I get the path for the current logged in user's My Documents folder?

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Alan Thomas
  • 1,006
  • 2
  • 14
  • 31
  • 1
    What you can do there is impersonate. But you need to stablish the user you want to use. – jcvegan Jun 03 '16 at 17:09
  • how will it know which user to get? – Daniel A. White Jun 03 '16 at 17:10
  • I'd like to get the currently logged in user's `My Documents` folder, if that's possible. – Alan Thomas Jun 03 '16 at 17:10
  • 2
    You have to know when a service is *not* an appropriate solution to a problem. Like this case, what are you going to do when multiple users log in, each running in their own session? The far more trivial solution is to start your program with a shortcut in the user's Startup folder or the Run registry key so you never have to guess who he might be and where his Documents folder is located. Having it a *lot* easier to debug and making it trivial for the user to opt-out and the ease of adding a UI are extra bonuses. – Hans Passant Jun 03 '16 at 17:32
  • @HansPassant I understand what you're saying, but this service will run on client's PC's who more likely that not will only have 1 user account, which are just sitting until they receive a print job. This service essentially intercepts the print job, processes it a bit and ideally spits it out to My Documents. We chose to make it a service so there was no (or far less) chance of a client accidentally/purposefully closing or stopping it, like they could with a background process. The service is set to launch on start up and restart if stopped. I just need a way for it to write to My Documents – Alan Thomas Jun 03 '16 at 17:40
  • All the more reason, Microsoft *strongly* recommends and will not support a service never does anything with a printer. Diagnosing problems is entirely too lousy. – Hans Passant Jun 03 '16 at 17:48
  • @HansPassant That seems odd to me considering Print Spooler is a service. Also, the service isn't interfacing with any printers/physical devices, it's simply watching a directory for new files, which are being added to the directory via a third party virtual printer. – Alan Thomas Jun 03 '16 at 17:55

1 Answers1

0

A service runs under a specific account, which is most likely not the same as the interactive user (typically, you).

Further, that service account likely doesn't have a My Documents folder.

For information on how to retrieve the interactive user from a Windows service running under a separate account, see this StackOverflow question.

Community
  • 1
  • 1
Mike Hofer
  • 16,477
  • 11
  • 74
  • 110
  • Funny, I just found that thread. But I do understand that the service doesn't run as the interactive user. It's running as `NT AUTHORITY\\SYSTEM`. And it certainly does not have a My Documents folder. Anyways, the answer in that thread enables me to get a string of the username correctly. Should I just build the path using that string, or can I use that somehow in the Environment.GetFolderPath() method? It's my understanding that the path to My Documents may be different for each machine, making me lean toward wanting to use that Environment method. But how can I? – Alan Thomas Jun 03 '16 at 17:30
  • Based on the remarks in your main question, I don't think you need to necessarily infer this dynamically at run time. Have you configured a configuration setting, instead? Sometimes, the simplest solutions are the best ones. – Mike Hofer Jun 03 '16 at 18:46