Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Using SHFileOperation.

Using SHFileOperation.

Scheduled Pinned Locked Moved C / C++ / MFC
helpdebuggingquestion
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    David Fleming
    wrote on last edited by
    #1

    I keep getting an error message telling me that the file cannot be found UNLESS I hard-code the name of the file to work on (in this case delete). Here's the code:

    SHFILEOPSTRUCT fileOp;
    CString sSrc; //this is actually declared and set earlier
    fileOp.hwnd = this->m_hWnd;
    sSrc = pItem->sCol4; //pointer to a STRUCT containing CStrings
    fileOp.pFrom = (LPCSTR)sSrc; //Source path+name
    fileOp.pTo = "\0"; //Unhandled exception if I don't set this
    fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
    fileOp.wFunc = FO_DELETE;
    int iRes = SHFileOperation(&fileOp);

    It seems apparent that the problem is in the conversion from the CString to LPCSTR for fileOp.pFrom. It works fine if I replace the line "fileOp.pFrom...." with

    fileOp.pFrom = "C:\\Dummy.txt";

    The strings look correct in the debugger window, so I'm at a loss here. I've tried various different castings and even tried using sSrc.GetBuffer(n) where n is various different values. None of those things seems to make a difference. So what's the snag? Any suggestions?

    M 1 Reply Last reply
    0
    • D David Fleming

      I keep getting an error message telling me that the file cannot be found UNLESS I hard-code the name of the file to work on (in this case delete). Here's the code:

      SHFILEOPSTRUCT fileOp;
      CString sSrc; //this is actually declared and set earlier
      fileOp.hwnd = this->m_hWnd;
      sSrc = pItem->sCol4; //pointer to a STRUCT containing CStrings
      fileOp.pFrom = (LPCSTR)sSrc; //Source path+name
      fileOp.pTo = "\0"; //Unhandled exception if I don't set this
      fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
      fileOp.wFunc = FO_DELETE;
      int iRes = SHFileOperation(&fileOp);

      It seems apparent that the problem is in the conversion from the CString to LPCSTR for fileOp.pFrom. It works fine if I replace the line "fileOp.pFrom...." with

      fileOp.pFrom = "C:\\Dummy.txt";

      The strings look correct in the debugger window, so I'm at a loss here. I've tried various different castings and even tried using sSrc.GetBuffer(n) where n is various different values. None of those things seems to make a difference. So what's the snag? Any suggestions?

      M Offline
      M Offline
      Michael Dunn
      wrote on last edited by
      #2

      pFrom must be a double-null-terminated string. It is actually the Win32 version of a string list - one null-terminated string after the other, with two nulls to mark the end. The version where you set pFrom to a string literal just happens to work, even though the correct literal is "c:\\dummy.txt\0". You'll need to set up a character buffer (not a CString because CString does not handle embedded nulls) and use that for pTo. --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm

      D 1 Reply Last reply
      0
      • M Michael Dunn

        pFrom must be a double-null-terminated string. It is actually the Win32 version of a string list - one null-terminated string after the other, with two nulls to mark the end. The version where you set pFrom to a string literal just happens to work, even though the correct literal is "c:\\dummy.txt\0". You'll need to set up a character buffer (not a CString because CString does not handle embedded nulls) and use that for pTo. --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm

        D Offline
        D Offline
        David Fleming
        wrote on last edited by
        #3

        I had noticed in the documentation that .pFrom (and .pTo) had to be double-null terminated, but I did not realize that CStrings would not handle the nulls. Thanks. Oh, BTW, it worked with "c:\\Dummy.txt", "c:\\Dummy.txt\0", and "c:\\Dummy.txt\0\0". However, I confess that I'm lame where string manipulation is concerned. I've fiddled with it and still can't get it to work. Here's what I've got:

        fileOp.hwnd = this->m_hWnd;
        sSrc = pItem->sCol4;
        char szSrc[255]; //my buffer for the string
        strcpy(szSrc, (LPCTSTR)sSrc); //this works fine
        int iSize = strlen(szSrc); //len appears OK
        strcat(szSrc, "\0\0"); //append double nulls
        iSize = strlen(szSrc); //debugger says len is same (?)
        fileOp.pFrom = szSrc;
        fileOp.pTo = "\0\0";
        fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
        fileOp.wFunc = FO_DELETE;
        SHFileOperation(&fileOp);

        Ugh! I'm clearly missing something rather fundamental. Thanks.

        M 1 Reply Last reply
        0
        • D David Fleming

          I had noticed in the documentation that .pFrom (and .pTo) had to be double-null terminated, but I did not realize that CStrings would not handle the nulls. Thanks. Oh, BTW, it worked with "c:\\Dummy.txt", "c:\\Dummy.txt\0", and "c:\\Dummy.txt\0\0". However, I confess that I'm lame where string manipulation is concerned. I've fiddled with it and still can't get it to work. Here's what I've got:

          fileOp.hwnd = this->m_hWnd;
          sSrc = pItem->sCol4;
          char szSrc[255]; //my buffer for the string
          strcpy(szSrc, (LPCTSTR)sSrc); //this works fine
          int iSize = strlen(szSrc); //len appears OK
          strcat(szSrc, "\0\0"); //append double nulls
          iSize = strlen(szSrc); //debugger says len is same (?)
          fileOp.pFrom = szSrc;
          fileOp.pTo = "\0\0";
          fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
          fileOp.wFunc = FO_DELETE;
          SHFileOperation(&fileOp);

          Ugh! I'm clearly missing something rather fundamental. Thanks.

          M Offline
          M Offline
          Michael Dunn
          wrote on last edited by
          #4

          strcat(szSrc, "\0\0"); has no effect. Watch the szSrc array in the memory watch window and you'll see. None of the C string functions work with embedded nulls, because the first null ends the string. What I do is zero-fill the array so no matter how long the actual file name is, there will be zeros after it. char szSrc[MAX_PATH+1] = {0}; --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm

          D 1 Reply Last reply
          0
          • M Michael Dunn

            strcat(szSrc, "\0\0"); has no effect. Watch the szSrc array in the memory watch window and you'll see. None of the C string functions work with embedded nulls, because the first null ends the string. What I do is zero-fill the array so no matter how long the actual file name is, there will be zeros after it. char szSrc[MAX_PATH+1] = {0}; --Mike-- Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm

            D Offline
            D Offline
            David Fleming
            wrote on last edited by
            #5

            Yeah, I noticed that the strcat(szSrc, "\0\0") did nothing. Thanks for the suggestion (zero filling the array) -- it worked like a charm. I just don't think I would have ever thought of it. BTW, I've enjoyed your articles. Keep up the excellent work and thanks a bunch.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups