Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Mai 19, 2024 03:52

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Fr Aug 26, 2011 13:05 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Ich habe einen Thread für einen Named Pipe server.
Wenn dieser eine neue nachricht geschickt bekommt, dann wird diese nachricht an einen Callback weitergeleitet (Syncronized).

Die Funktionen im Callback nehmen die Nachricht auseinander (String > UTF8 > WideString) und
machen daraus Dateipfade die auch 100% stimmen.

Diese Dateipfade werden auf existenz überprüft WideFileExists() welches nur nen FindFirstW macht um zu gucken ob die Datei da ist.
Funktioniert auch, zumindest für die meisten Dateien.

Was komischerweise nicht funktioniert, sind dateien bei mir auf in einem bestimmten Ordner.
Da liefert FindFirstW das die Datei nicht existiert, obwohl der komplette Dateipfad 100% richtig ist und
die Datei natürlich existiert.

Das ist mein Hauptproblem erstmal das es Dateien gibt, bei denen FindFirst zurückwirft das diese nicht existiert
obwohl diese da ist.



So nun kommt aber der hammer, diese Anwendung hat noch nen einfaches Explorer Drag & Drop (WM_DROPFILES).
Wenn ich die exakt gleiche Datei in die Anwendung ziehe, dann wird diese erkannt und alles passt inkl. WideFileExists().


Aber über den named pipe thread wird diese nicht erkannt. (Ratlos)

Achja problem tritt nur unter Vista/Win7 auf!

Hier ein bischen code:

Code:
  1.  
  2. // Callback in der Mainform (FOnReceive vom TXPipeServer)
  3. procedure TfrmMain.NewPipeMessage(Sender : TObject; AKind : byte; AMsg : String);
  4. var
  5.   WMsg : WideString;
  6. begin
  7.   WMsg := UTF8ToWideString(AMsg);
  8.   if WideFileExists(WMsg) then
  9.   begin
  10.     // Do something with the good file
  11.   end;
  12. end;
  13.  


Code:
  1.  
  2. procedure TXPipeServer.ReceivedSyncronized;
  3. begin
  4.   if Assigned(FOnReceive) then
  5.     FOnReceive(Self, FCurKind, FCurMsg);
  6. end;
  7.  
  8. procedure TXPipeServer.Execute;
  9. var
  10.   I, Written: Cardinal;
  11.   InMsg, OutMsg: TXPIPEMessage;
  12.   StrMsg : String;
  13. begin
  14.   while not Terminated do
  15.   begin
  16.     if FHandle = INVALID_HANDLE_VALUE then
  17.     begin
  18.       // suspend thread for 250 milliseconds and try again
  19.       Sleep(250);
  20.     end else begin
  21.       if ConnectNamedPipe(FHandle, nil) then
  22.       try
  23.         // read data from pipe
  24.         InMsg.Size := SizeOf(InMsg);
  25.         ReadFile(FHandle, InMsg, InMsg.Size, InMsg.Size, nil);
  26.         if
  27.           (InMsg.Kind = 0) and
  28.           (StrPas(InMsg.Data) = cShutDownMsg + FPipeName)
  29.         then
  30.         begin
  31.           // process shut down
  32.           OutMsg.Kind := 0;
  33.           OutMsg.Count := 3;
  34.           OutMsg.Data := 'OK'#0;
  35.           Terminate;
  36.         end else begin
  37.           StrMsg := StrPas(InMsg.Data);
  38.  
  39.           // Send received message to callback
  40.           FCurKind := OutMsg.Kind;
  41.           FCurMsg := StrMsg;
  42.           Synchronize(ReceivedSyncronized);
  43.  
  44.           OutMsg := InMsg;
  45.           // we'll just reverse the data sent, byte-by-byte
  46.           for I := 0 to Pred(InMsg.Count) do
  47.             OutMsg.Data[Pred(InMsg.Count) - I] := InMsg.Data[I];
  48.         end;
  49.         CalcMsgSize(OutMsg);
  50.         WriteFile(FHandle, OutMsg, OutMsg.Size, Written, nil);
  51.       finally
  52.         DisconnectNamedPipe(FHandle);
  53.       end;
  54.     end;
  55.   end;
  56. end;
  57.  


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 26, 2011 13:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Code:
  1.           for I := 0 to Pred(InMsg.Count) do
  2.             OutMsg.Data[Pred(InMsg.Count) - I] := InMsg.Data[I];

Wenn der String nullterminiert ist, hast du dann als erstes Zeichen in OutMsg.Data ein #0, was von Delphi zwar ignoriert wird, aber von den ganzen API-Funktionen nicht. Die brechen nach dem #0-Byte ab und halten das für einen leeren String.
Versuch mal:
Code:
  1.           for I := 0 to Pred(InMsg.Count)-1 do
  2.             OutMsg.Data[Pred(InMsg.Count) - (I+1)] := InMsg.Data[I];


greetings.

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 26, 2011 20:22 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Hab den Übeltäter gefunden, mein Commandline/Argument Parser kommt mit einem zusätzlichen Leerzeichen im Dateinamen nicht zurecht.

Also sowas z.b. "Folge - 04 Tolle Serie.avi" würde nicht erkannt werden wegen dem Doppel-Leerzeichen.
Es kommt dann raus "Folge - 04 Tolle Serie.avi".

Da muss ich mich nochmal hinsetzten um das beheben.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Aug 26, 2011 22:33 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
So problem behoben:

Code:
  1.  
  2. procedure GetArgumentsFromCmd(AFullArgs : PWideChar; ALst : TTNTStrings);
  3. var
  4.   P : PWideChar;
  5.   Buffer : WideString;
  6.   InQuote : Boolean;
  7.   L, I : Integer;
  8. begin
  9.   P := AFullArgs;
  10.   L := Length(AFullArgs);
  11.   I := 0;
  12.   Buffer := '';
  13.   InQuote := False;
  14.   while (I < L) do
  15.   begin
  16.     if P^ = '"' then
  17.     begin
  18.       if InQuote then
  19.       begin
  20.         InQuote := False;
  21.         ALst.Add(Buffer);
  22.         Buffer := '';
  23.       end
  24.       else
  25.       begin
  26.         Buffer := '';
  27.         InQuote := True;
  28.       end;
  29.       Buffer := '';
  30.     end
  31.     else if (P^ = ' ') and (not InQuote) then
  32.     begin
  33.       if Buffer <> '' then
  34.         ALst.Add(WideTrim(Buffer));
  35.       Buffer := ' ';
  36.     end
  37.     else
  38.       Buffer := Buffer + P^;
  39.  
  40.     Inc(P);
  41.     Inc(I);
  42.   end;
  43.  
  44.   if Buffer <> '' then
  45.     ALst.Add(WideTrim(Buffer));
  46. end;
  47.  


So kann man daraus z.b. den Dateinamen als Argument rausziehen.

Code:
  1.  
  2. procedure TForm1.Button2Click(Sender: TObject);
  3. var
  4.   S : WideString;
  5.   Lst : TTNTStrings;
  6.   I : Integer;
  7. begin
  8.   S := TntEdit1.Text;
  9.  
  10.   Lst := TTNTStringList.Create;
  11.   GetArgumentsFromCmd(PWideChar(S), Lst);
  12.  
  13.   Filename := '';
  14.   Memo1.Lines.Clear;
  15.   For I := 1 to Lst.Count-1 do
  16.   begin
  17.     Filename := Filename + Lst[I] + ' ';
  18.   end;
  19.   Memo1.Lines.Add(WideTrim(S));
  20.  
  21.   Lst.Free;
  22. end;
  23.  


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]