Auf Mobil Device über C++ zugreifen



  • Hallo Zusammen!

    Ich möchte auf die Speicherkarte eines Messgerätes in C++ zugreifen. Dies verhält sich so wie ein Mobiltelefon. Es wird im Windowsexplorer unter Andere Geräte angezeigt. Aber welchen Pfad hat die Speicherkarte? Kann ich in Windows irgendwie einstellen das diese Speicherkarte eine Laufwerksbuchstaben bekommt? Am Messgerät und wie sich das an Windows anmeldet kann ich nichts ändern.

    Unter Windows kann ich die Dateien auf der Speicherkarte auch ohne Probleme benutzen. Das müsste ich in C++ auf können. Vielleicht hat jemand eine Idee.

    Danke für alle Ideen!

    mfg Harald

    PS.: Ich hoffe ich bin im richtigen Forum! Wenn nicht bitte verschieben



  • Jetzt mal nur eine Idee, vielleicht geht es auch einfacher.
    Wenn du es per Explorer öffnen kannst, kannst du ja immer noch die Explorer-Funktionalität nachbauen.
    Also per SHGetDesktopFolder das Root-Objekt beziehen und per EnumObjects die Daten auslesen. Wenn das entsprechende Gerät gefunden wurde, sollte man die Daten per BindToObject und wiederrum EnumObjects auslesen können. Es gibt auch ein komplettes Beispielprogramm bei Microsoft, das diese Funktionalität demonstriert, den Link habe ich aber leider jetzt nicht gefunden.



  • Danke für die rasche Antwort!

    Kannst du mir das etwas genauer beschreiben mit Beispielcode wenns möglich wäre. Hab keine Ahnung wie ich diese Befehle anwende. Auch mit Google komm ich auf keine richtige Lösnung.

    IShellFolder *ppshf;
    	SHGetDesktopFolder(&ppshf);
    	LPENUMIDLIST pEnumIDList;
    	ppshf->EnumObjects(NULL,(SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN | SHCONTF_NONFOLDERS),&pEnumIDList);
    

    Das ist mein bisheriger Code. Wie mach ich jetzt weiter damit ich auf das Gerät das zum Beispiel den Namen C650 trägt zugreifen kann. Oder ich überhaupt abfrage ob es da ist?

    mfg Harald



  • Ich habe mir mal eine Klasse CNode gebaut, die Funktionalität dürfte aber ersichtlich werden.
    Erst einmal den Root (Desktop) einlesen.

    bool GetItems(CNode*& pRoot)
    {
    	LPITEMIDLIST      pidl;
    	if(SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl)))
    	{
    		LPSHELLFOLDER     pDesktop;
    		if(FAILED(SHGetDesktopFolder(&pDesktop)))
    			return false;
    		if(!pRoot) pRoot = new CNode;
    		pRoot->SetParentFolder(NULL);
    		pRoot->SetPidlRel(pidl);
    		pRoot->SetPidlFQ(PidlCopy(pidl));
    		pDesktop->Release();
    		return true;
    	}
    	return false;
    }
    

    Anschließend können immer die ChildItems eines Knotens ausgelesen werden.

    bool GetChildItems(CNode* pFolder)
    {
    	IShellFolder*  pParentFolder = NULL;
    	HRESULT        hr;
    	if(!pFolder->GetParentFolder())
    	{
    		hr = SHGetDesktopFolder(&pParentFolder);
    	}
    	else
    	{
    		hr = pFolder->GetParentFolder()->BindToObject(pFolder->GetPidlRel(), NULL, IID_IShellFolder2, (LPVOID*)&pParentFolder);
    	}
    	if(!pParentFolder|| hr!=S_OK)
    		return false;
    	size_t size = pFolder->GetData().size();
    	size_t enumsize = EnumObjects(pFolder,pParentFolder,true);
    	if(size==0 || enumsize!=size)
    	{
    		pFolder->DeleteAll();
    		EnumObjects(pFolder,pParentFolder,false);
    	}
    	pParentFolder->Release();
    
    	return true;
    }
    

    Die EnumObjects-Methode kann ich hier nicht komplett hinschreiben, ich kann dir das Ganze aber per Mail schicken, wenn du möchtest.

    size_t EnumObjects(CNode* pFolder,IShellFolder* pParentFolder, bool JustCount)
    {
    	LPENUMIDLIST   pEnum;
    
    	if(!pParentFolder)
    	{
    		return 0;
    	}
    	if(SUCCEEDED(pParentFolder->EnumObjects(NULL,
    											SHCONTF_FOLDERS  /*| SHCONTF_NONFOLDERS*/ | SHCONTF_INCLUDEHIDDEN,
    											&pEnum)))
    	{
    
    		if(pEnum==NULL)
    			return 0;
    		LPITEMIDLIST	pidlTemp;
    		CNode*			pItem;
    		SHFILEINFO		sfi;
    
    		while(S_OK == (pEnum->Next(1, &pidlTemp, &dwFetched)) && dwFetched)
    		{
                      // ...
                      CoTaskMemFree(pidlTemp);
             }
         }
    pEnum->Release();
    

    Per SHCONTF_NONFOLDERS können auch Dateien angefordert werden.
    Jetzt kann das Einlesen z.B. so gehen:

    CNode* pRoot=0;
    if(GetItems(pRoot))
    {
    	if(GetChildItems(pRoot))
    	{
             // .. 
             // hier kann jetzt GetChildItems für jedes Child des Roots aufgerufen
             // werden u.s.w. (-> Treeview)
        }
    }
    if(pRoot)
      delete pRoot;
    


  • Danke Vicious Falcon!

    Du bist wirklich eine große Hilfe!

    Leider schaffe ich es nicht die Klasse NCode nachzubilden. Vielleicht kanst du mir die Definiton noch posten. Ich hoffe das es dann läuft und ich mich selbst noch etwas spielen kann um die restlich Funktionalität herauszufinden.

    Vielleicht noch folgende Frage vorab. Wo überprüfe ich den Name des Ordners bzw. des Gerätes um den Richtigen zu finden?

    Besten Dank noch mal
    mfg Harald



  • Kann es kurz einer bitte bestätigen/widerlegen, dass bspw. Webcams im Explorer auch unter "Andere Geräte" angezeigt werden.
    Falls es nämlich so ist, müsste man evtl. einen anderen Weg gehen.

    ICreateDevEnum* pCreateDevEnum=0;
    if(SUCCEEDED(CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pCreateDevEnum))))
    {
      HRESULT hr;
      IEnumMoniker* pEm=0;
      IMoniker* pM;
      ULONG cFetched;
      hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
      if(hr == NOERROR)
      {
      pEm->Reset();
      while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
      {
        IPropertyBag* pBag=0;
        hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
        if(SUCCEEDED(hr))
        {
          VARIANT var;
          ar.vt = VT_BSTR;
          hr = pBag->Read(L"FriendlyName", &var, NULL);
          if(SUCCEEDED(hr))
          {
          // hier var.bstrVal auswerten
             SysFreeString(var.bstrVal);
          }
        }
    }
    // die ganzen Release-Methoden müssen natürlich aufgerufen werden
    

    Dies ist nur ein Beispiel für CLSID_VideoInputDeviceCategory (TV-Karten/Webcams), vielleicht kannst du für dein device aber eine passende CLSID finden...



  • Zuerst muss ich mich wirklich nochmals für die große Hilfe in diesem Forum bedanken.

    Nun ein kurzes Update.
    Über das nachbauen der Explorer-Funktionalität (per SHGetDesktopFolder das Root-Objekt beziehen und per EnumObjects die Daten auslesen) funktioniert es nicht auf „andere Geräte“ zuzugreifen. Sie werden einfach nicht dargestellt. Man sieht nur Laufwerke und Systemordner, wie Netzwerkumgebung, ... .

    Ich kann bestätigen, dass Kameras ebenfalls unter andere Geräte angezeigt werden!

    Leider ist das ganze für mich ziemlich neu und ich verstehe sehr wenig von dem Alternativweg den Vicious Falcon beschrieben hat. Was ist eine CLSID. Woher bekommt man die für ein beliebiges Gerät? Muss man die in den Code einbinden, wie eine DLL oder ist das eine art Pointer den man allokieren muss?

    Eine weitere Möglichkeit die mir noch offen steht ist folgende. Man kann eine Verknüpfung erstellen, die ich beispielsweise auf C: lege. Ist es in C++ möglich über eine Verknüpfen auf ein Verzeichnis zuzugreifen?? Gibt es dafür einen Befehl?

    mfg
    Harald


Anmelden zum Antworten