I don't know if there's a better way, but I just parse it with some reasonable heuristics. Here's a clip from a hotlink control I did a while back. Should give you an idea of how I parse the command string as supplied by the user:

Code:
void CXHotlink::OnLButtonDown(CView* /*pView*/, UINT /*nFlags*/, const CPoint& /*point*/)
{
  CString cs;
  wchar_t *p,*q,buf1[MAX_PATH],buf2[MAX_PATH];
  long i;
  HINSTANCE rc;  //shellexecute() returns an HINSTANCE.

  if(m_PropStruct.nAction>0){
    p=wcschr(m_PropStruct.LinkText,L'\"');
    if(p){
      q=wcschr(p+1,L'\"');
      if(q){
        //somethying is enclosed in quotes
        //copy everything between the quotes to the first buffer
        wcsncpy_s(buf1,MAX_PATH,p+1,q-(p+1));
        //copy the rest to the second buffer
        wcsncpy_s(buf2,MAX_PATH,q+1,MAX_PATH-1);
      }else{
        //malformed
        AfxMessageBox(L"Unable to parse command string.",MB_ICONERROR);
        return;
      }
    }else{
      //no quotes      
      //find space separator
      p=wcschr(m_PropStruct.LinkText,L' ');
      if(p){
        wcsncpy_s(buf1,MAX_PATH,m_PropStruct.LinkText,p-m_PropStruct.LinkText);
        //copy the rest to the second buffer
        wcsncpy_s(buf2,MAX_PATH,p+1,MAX_PATH-1);        
      }else{
        wcsncpy_s(buf1,MAX_PATH,m_PropStruct.LinkText,MAX_PATH-1);
        buf2[0]=0;
      } 
    }
    rc=ShellExecute(AfxGetMainWnd()->m_hWnd,L"open",buf1,buf2,NULL,1);
    if((int)rc<33){
      AfxMessageBox(L"Unable to launch program",MB_ICONERROR);
    }
  }else{
    i=wcstol(m_PropStruct.LinkText,NULL,10);
    
    AfxGetMainWnd()->PostMessage(WM_GOTOVIEW,i,0);
  }


}