none
Win32_Share not returning local path for a share folder RRS feed

  • Question

  • Hi all,

    I fell in a endless hole and I need help to get out. My purpose is to convert UNC paths to local drive paths when the share belongs to the machine where the program is installed.

    I wrote the typical  solution for this: querying the WIN32_Share as follows

    var scope = new ManagementScope(@"\\.\root\cimv2");
    var query = new SelectQuery("SELECT * FROM Win32_Share WHERE Name = '" + shareName + "'");
    var searcher = new ManagementObjectSearcher(scope, query)

    etc...etc

    When I run the code above as a Console program, everything works my UNC is converted to local.

    When I run that in a WINDOWS SERVICE, Path Property ALWAYS comes EMPTY.

    I'm talking about same permissions, same user, same program...run in different ways.

    Can anyone help me?

    Thanks.

    PD. I've tried, Impersonation, sending username and password, and all kind of combination of things that you can imagine.


    C# programmer

    Tuesday, November 15, 2016 8:53 PM

All replies

  • Please check the permission of your service as mentioned in the remarks here.

    https://msdn.microsoft.com/en-us/library/aa394435(v=vs.85).aspx

    Remarks

    Depending on your security permissions, you may not be able to retrieve all of the properties of this class.     For example, AllowMaximum, MaximumAllowed,      Path, and Type properties may return null. Generally     speaking, Power Users and Administrators will be able to retrieve all property values.


    See if you service is under impersonation when this code is running.
    Wednesday, November 16, 2016 3:06 AM
    Answerer
  • Btw, the following code works for me with my current credential:

    using System;
    using System.Collections.Generic;
    using System.Management;
    using System.ServiceProcess;
    
    
    namespace ServiceTest
    {
        public partial class TestService : ServiceBase
        {
            private System.Threading.Thread t;
            private volatile bool done = false;
    
            public TestService()
            {
                InitializeComponent();
            }
    
            protected override void OnStart(string[] args)
            {
                t = new System.Threading.Thread(new System.Threading.ThreadStart(Work));
                t.Start();
            }
    
            protected override void OnStop()
            {
                if ((t != null) && (t.ThreadState == System.Threading.ThreadState.Running))
                {
                    done = true;
                    t.Join();
                    t = null;
                }
            }
    
            private void Work()
            {
                var scope = new ManagementScope(@"\\.\root\cimv2");
                var query = new SelectQuery("SELECT * FROM Win32_Share WHERE Name = 'Shared'");
                var searcher = new ManagementObjectSearcher(scope, query);
                List<string> path = new List<string>();
                foreach (ManagementObject share in searcher.Get())
                {
                    path.Add(Convert.ToString(share["Path"]));
                }
                while (!done)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }
        }
    }

    Replace "Shared" pathname I hardcoded here with the share name you're testing for.

    When you insert a breakpoint at the sleep statement, you should be able to see path[0] is set to the physical path of your share.



    Wednesday, November 16, 2016 3:37 AM
    Answerer
  • Hi Remixcr,

    >>When I run that in a WINDOWS SERVICE, Path Property ALWAYS comes EMPTY.

    As far as I know, Local service doesn't have rights to network shares. You need to run your service as a user with appropriate permissions, most likely a domain user with rights to the shares.

    Best regards,

    Kristin


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, November 16, 2016 7:20 AM
  • Correct, that works for me either, but when I run it in a Windows Service, the "Path" property comes empty.

    C# programmer

    Wednesday, November 16, 2016 1:30 PM
  • Sorry I forgot to mention that I'm running the service under a domain account.

    C# programmer

    Wednesday, November 16, 2016 1:31 PM
  • Hi,

    I'm running my service under a domain account, the same I use when test running as a console program. That said, how can I verify if that piece of code is running under impersonation?


    C# programmer

    Wednesday, November 16, 2016 1:33 PM
  • Let me try this, maybe my problem is that the code is being called inside a dll.

    C# programmer

    Wednesday, November 16, 2016 1:43 PM
  • Nothing of this works when running as a service. I think there is no solution to my problem. I have to say that my Windows services is also a WCF service, but is running under the correct account, because Integrated security works perfectly for database connections.

    C# programmer

    Wednesday, November 16, 2016 8:15 PM
  • Okay, let's try refine the steps:

    1) Download the test project that I created here:

    https://1drv.ms/u/s!AhQxiQzVY1P5i79lO3rNYhojdqOu1g

    2) Replace the share name with the one you want to test for.

    3) Install the service with "InstallUtil ServiceTest.exe". Type your domain account name and password when prompted for it.

    4) Start it with "sc start ServiceTest".

    5) Place a breakpoint there and watch the path resolves.

    When test is done:

    6) Stop the service with "sc stop ServiceTest".

    7) Uninstall it with "InstallUtil /u ServiceTest.exe". 

    Thursday, November 17, 2016 2:32 AM
    Answerer
  • You can check it with
    System.Security.Principal.WindowsIdentity.GetCurrent().Name
    
    Thursday, November 17, 2016 2:38 AM
    Answerer
  • Correct I've also tried creating impersonation context:

    using (WindowsImpersonationContext impersonatedUser = newId.Impersonate()) {

    }

    The user running the service seems to be fine, but still doesn't retrieve that.

    I'll try your code, it can be an environmental thing.


    C# programmer

    Friday, November 18, 2016 2:05 PM
  • The Win32 function NetShareGetInfo can return the local path of the shared directory in SHARE_INFO_2::shi_path. I was thinking you could try that instead of WMI, and if it doesn't work, perhaps it returns an error code that helps you solve the problem.

    However, the NetShareGetInfo documentation already says that information levels 2, 502, and 503 are only available if the caller is an interactive user or has "Administrator, Power User, Print Operator, or Server Operator group membership". If the WMI class Win32_Share internally uses NetShareGetInfo, that would explain why it does not return the path when called from a service.

    Perhaps it will work if you add the domain account to one of those groups, then. 

    Sunday, November 20, 2016 9:46 AM