CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Apr 2007
    Location
    South Africa
    Posts
    86

    Windows Service, Threads and fstream

    I've written an application which writes some data to disk every few seconds to keep the hard drive awake.

    Since this application must run all the time I decided to convert it to a Windows Service.

    After hours of studying, coding and testing it finally looks as though I've got it right. My service installs, starts, stops etc. My only problem is that the code that writes to disk doesn't work anymore, e.g the file doesn't get written to disk. I really have no idea what the problem could be.

    The code is contained in a thread:

    PHP Code:
    unsigned __stdcall ServiceWorkerThread(void pVoid)
    {
        
    endWorkerThread = ::CreateEvent(0TRUEFALSE0);
        
        
    long data 1000;
        
        
    serviceRunning true;

        while (
    serviceRunning == true)
        {
            
    std::wofstream dfile;
            
    dfile.open(L"data.txt"std::ios::out);
            
    data data 1;
            
    dfile << data;
            
    dfile.close();
            
    Sleep(25000);
        }
        ::
    SetEvent(endWorkerThread);
        return 
    0;

    The thread is started as follows:

    PHP Code:
    void StartWorkerThread()
    {
        
    hThread reinterpret_cast<HANDLE>(::_beginthreadex(NULL,
                     
    NULL,
                     
    ServiceWorkerThread,
                     
    NULL,
                     
    NULL,
                     
    NULL));
        return;

    I've tried debugging the service and I can see that the thread gets called and I can step through it, but wofstream looks extremely complex and I can't make out whats going on inside it.

    So what's causing the problem? Is it the thread or the service part, or both?

    If anyone can shed some light on this it will be greatly appreciated.

  2. #2
    Join Date
    Apr 2007
    Location
    South Africa
    Posts
    86

    Re: Windows Service, Threads and fstream

    I just want to add that I have the following piece of code which only runs when the service is installed / removed and it works 100% which further leads me to believe that its got something to do with the service / thread code.

    PHP Code:
    void WriteLog(std::wstring text)
    {
        
    std::wofstream file;
        
    file.open(L"log.txt"std::ios::out std::ios_base::app);
        
    file << text << std::endl;
        
    file.close();
        return;


  3. #3
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    Re: Windows Service, Threads and fstream

    How are you concluding that the data is not being written ? Are you sure you are looking at the right location for the file ? HAve you tried using a hardcoded absolute path for example ?

  4. #4
    Join Date
    Jul 2008
    Location
    Cochin, Kerala
    Posts
    145

    Smile Re: Windows Service, Threads and fstream

    test with condition :

    if( dfile.is_open() ) { } to confirm whether the file is opened sucessfully or not.

    and why dont you try...

    std:fstream file;
    file.open("C:\\sample.txt",file.out);
    if( !file.is_open() )
    {
    cout<<"File open failed!"<<endl;
    }

    think this may helps.. cheers

  5. #5
    Join Date
    Apr 2007
    Location
    South Africa
    Posts
    86

    Re: Windows Service, Threads and fstream

    Thanks guys, you saved me! It never occurred to me that I can provide the full path name. When I hardcode the absolute path e.g C:\\sample.txt it works 100%. So I guess it gets written to disk in some unknown location when I do not provide the full path.

    Why is this? As I said in my previous post the following code generates the .txt file in the same location as the executable:

    PHP Code:
    void WriteLog(std::wstring text

        
    std::wofstream file
        
    file.open(L"log.txt"std::ios::out std::ios_base::app); 
        
    file << text << std::endl
        
    file.close(); 
        return; 

    But this code which runs in another thread gets written somewhere else:

    PHP Code:
    while (serviceRunning == true)
        {
            
    std::wofstream dfile;
            
    dfile.open(L"D:\\data.txt"std::ios::out);
            
    data data 1;
            
    dfile << data;
            
    dfile.close();
            
    Sleep(25000);
        } 
    I'm just trying to figure out why this is so. Any further insight is welcome!

  6. #6
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    Re: Windows Service, Threads and fstream

    You mean, even after specifying absolute path, you don't find it? Why not search and see where it is being created? Perhaps you can see some pattern. Also, is D driver a mapped drive by any chance ?

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Windows Service, Threads and fstream

    Quote Originally Posted by links
    I'm just trying to figure out why this is so. Any further insight is welcome!
    The currentdirectory is used when you don't supply a complete file path in a file operation. This current directory can depending on how the app was started (e.g. specifying a different start up folder when using create process) or if the application internally changes it (using SetCurrentDirectory). In the case of services, I believe the current directory is set to the location of the SCM. If you want to know what the current directory is use GetCurrentDirectory.

    That all being said, rather than writing to a file to keep the harddrive on, how about turning off the power saving options?

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,633

    Re: Windows Service, Threads and fstream

    So I guess it gets written to disk in some unknown location when I do not provide the full path.
    Your "some unknown location" most likely is %WINDIR%\system32
    Best regards,
    Igor

  9. #9
    Join Date
    Apr 2007
    Location
    South Africa
    Posts
    86

    Re: Windows Service, Threads and fstream

    Thanks for all the replies.

    And indeed, I found the text file in Windows\System32! So, as Arjay stated, the current directory gets changed to the location of the SCM. GetCurrentDirectory led me to SetCurrentDirectory so I'm going to adapt my code to change the directory back to my service's exe directory.

    Unfortunately merely changing the power saving settings isn't an option in my case. Its a HP laptop with an extremely limited BIOS. After a hard disk replacement the disk is shut down every minute or so irrespective of the power settings in Windows. All I can think is that the BIOS is set to a much more aggresive setting and overrides the Windows settings.

    I wouldn't have gone through all the trouble to write this service if it weren't absolutely necessary!

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Windows Service, Threads and fstream

    IMO opinion Set[Get]CurrentDirectory usually causes issues because unless you immediately set the currentdirectory, you can't rely that GetCurrentDirectory will return the correct value. I say this because any [3rd party] dll may change the current directory. Instead use GetModuleFileName(...) at the start of the service and store the value for use later.
    Last edited by Arjay; August 20th, 2008 at 10:03 AM.

  11. #11
    Join Date
    Jul 2008
    Location
    Cochin, Kerala
    Posts
    145

    Smile Re: Windows Service, Threads and fstream

    The GetSystemPowerStatus function retrieves the power status of the system. The status indicates whether the system is running on AC or DC power, whether the battery is currently charging, and how much battery life remains.

    BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS lpSystemPowerStatus);

    cheers

  12. #12
    Join Date
    Feb 2000
    Location
    San Diego, CA
    Posts
    10,354

    Re: Windows Service, Threads and fstream

    GetModuleFileName is a better alternative. But, depending on where the exe is placed, the location might be forbidden to be written into. For e.g. if the exe were to be in Program Files folder and the service were to be per user, it probably wouldn't work unless the user has privileges to write to the location. Just something to keep in mind.

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Windows Service, Threads and fstream

    Agreed, I didn't mention this earlier but you can use SHGetFolderPath api to retrieve valid areas to write to. Check out the FolderID_Documents and FolderID_LocalAppData constants.

  14. #14
    Join Date
    Apr 2007
    Location
    South Africa
    Posts
    86

    Re: Windows Service, Threads and fstream

    I've used GetModuleFileName and SetCurrentDirectory and it works great.
    Thanks for all the help.

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Windows Service, Threads and fstream

    Quote Originally Posted by links
    I've used GetModuleFileName and SetCurrentDirectory and it works great.
    Thanks for all the help.
    You missed the point about SetCurrentDirectory.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured