<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Probleme mit SHFileOperation oder FindFirst&#x2F;FindNext (VCL) unter Win2k]]></title><description><![CDATA[<p>hallo!</p>
<p>ich bastele gerade ein programm, das beim runterfahren und hochfahren von windows bestimmte dateien und ordner hin und her kopiert.<br />
ich benutze dafür an der basis die <strong>FindFirst()</strong>- und <strong>FindNext()</strong>-Funktionen und die WinAPI-Funktion <strong>SHFileOperation()</strong>.<br />
Mit <strong>FindFirst()</strong> und <strong>FindNext()</strong> filtere ich rekursiv Dateien raus, die ein bestimmtes Alter überschreiten.</p>
<p>Nun habe ich folgendes Problem:</p>
<p>Beim Sichern der Daten läuft das Programm unter WinXP SP1 &quot;völlig normal&quot;, d.h. die Kopieroperationen mittels <strong>SHFileOperation()</strong> werden in ähnlicher Geschwindigkeit durchgeführt, wie wenn man es von Hand kopieren würde. Unter Win2k allerdings verhält sich das Programm sehr merkwürdig: das Kopieren dauert SUPER lange und wenn ich in den TaskManager gucke wundert mich das auch nicht, denn der Process kriegt einfach keine CPU-Zeit ab, obwohl sonst nichts Großes läuft.</p>
<p>Das Merkwürdige an der Sache ist, dass die <strong>SHFileOperation()</strong> für sich allein gut läuft (unter WinXP und Win2k). Die <strong>FindFirst()-/FindNext()</strong>-Schleifen laufen ohne die Kopieroperation auch einwandfrei (Test über Ausgabe in einem Memo). Nur wenn ich beide zusammenführe, bekomme ich das beschriebene verhalten.</p>
<p>Weiß jemand wieso???</p>
<p>Hier noch ein bisschen Quellcode:</p>
<p>[cpp]// Funktion zum Kopieren/Bewegen von Dateien/Ordnern<br />
// mode = FO_COPY oder FO_MOVE<br />
void __fastcall TDataSafeTest::MyCopy(const CHAR source[MAX_PATH], const CHAR dest[MAX_PATH], int mode)<br />
{<br />
<strong>SHFILEOPSTRUCT fop;</strong><br />
CHAR l_Dest[MAX_PATH];<br />
CHAR l_Source[MAX_PATH];</p>
<p>fill_n(l_Dest, MAX_PATH, '\0');<br />
fill_n(l_Source, MAX_PATH, '\0');</p>
<p>strcpy(l_Dest, dest);<br />
strcpy(l_Source, source);</p>
<p>fop.hwnd = NULL;<br />
fop.wFunc = mode;<br />
fop.pFrom = l_Source;<br />
fop.pTo = l_Dest;<br />
fop.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR; // keine Dialoge anzeigen beim Kopieren<br />
fop.fAnyOperationsAborted = 0;<br />
fop.hNameMappings = NULL;<br />
fop.lpszProgressTitle = NULL;</p>
<p><strong>SHFileOperation( &amp;fop );</strong><br />
}[/cpp]</p>
<p>[cpp]// SaveNewerData speichert eine angegebene Quelle an den angegebenen Zielort,<br />
// wenn die Quelle neuer ist, als das angegebene Datum ( Aufruf von MyCopy() ).<br />
//<br />
void __fastcall TDataSafeTest::SaveNewerData( const CHAR Src[MAX_PATH],<br />
const CHAR Dst[MAX_PATH],<br />
TDateTime TimeOfLastBackup )<br />
{<br />
TSearchRec SR;<br />
CHAR Source[MAX_PATH]; strcpy(Source, Src);<br />
CHAR Dest[MAX_PATH]; strcpy(Dest, Dst);<br />
AnsiString TmpSrc, TmpDest;</p>
<p>/* ein Versuch, die Prozesspriorität hochzusetzen, leider erfolglos<br />
int oldPriorityClass, oldPriority;<br />
oldPriorityClass = GetPriorityClass(GetCurrentProcess);<br />
oldPriority = GetThreadPriority(GetCurrentThread);<br />
SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS);<br />
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_IDLE);<br />
*/</p>
<p><strong>if( FindFirst( AnsiString(Src), faAnyFile, SR ) == 0 )</strong>{</p>
<p>// Unterscheidung zwischen Dateien und Ordnern<br />
if( (SR.Attr &amp; faDirectory) == 0 ){ // es handelt sich um eine Datei</p>
<p>if( FileDateToDateTime(SR.Time) &gt; TimeOfLastBackup ){<br />
TmpDest = AnsiString(Dst)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;<br />
strcpy(Dest, TmpDest.c_str() );<br />
MyCopy( Source, Dest, FO_COPY );<br />
}<br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; ){</p>
<p>// es handelt sich um einen Ordner mit Namen ungleich . und ..<br />
TmpDest = AnsiString(Dest)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>; // neuer Unterordner</p>
<p>ForceDirectories( TmpDest );</p>
<p><strong>if( FindFirst(AnsiString(Src)+&quot;\*&quot;, faAnyFile, SR) == 0 )</strong>{<br />
if( m_LongLog ) LogAddEntry(&quot;FindFirst: &quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>,1);<br />
// es existieren Dateien/Ordner in dem zu kopierenden Ordner<br />
TmpSrc = AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;</p>
<p>if( FileExists(TmpSrc) ){<br />
strcpy(Dest, (TmpDest+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
strcpy(Source, (AnsiString(Source)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
<strong>MyCopy(Source, Dest, FO_COPY);</strong><br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; &amp;&amp; DirectoryExists(TmpSrc) ){<br />
strcpy(Dest, TmpDest.c_str());<br />
strcpy(Source, (AnsiString(Source)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
SaveNewerData(Source, Dest, TimeOfLastBackup);<br />
}<br />
if( m_LongLog ) LogAddEntry(&quot;EndFind&quot;,-1);<br />
}<br />
// durchlaufe alle Einträge in dem angegebenen Ordner rekursiv<br />
<strong>while( FindNext(SR) == 0 )</strong>{<br />
if( m_LongLog ) LogAddEntry(&quot;FindNext: &quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>,1);<br />
TmpSrc = AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;</p>
<p>if( FileExists(TmpSrc) ){<br />
strcpy(Dest, (TmpDest+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
strcpy(Source, (AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());</p>
<p><strong>MyCopy(Source, Dest, FO_COPY);</strong><br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; &amp;&amp; DirectoryExists(TmpSrc) ){<br />
strcpy(Dest, TmpDest.c_str());<br />
strcpy(Source, (AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());</p>
<p>SaveNewerData(Source, Dest, TimeOfLastBackup);<br />
}<br />
}<br />
}<br />
}<br />
FindClose(SR);</p>
<p>/* gehört zum Prioritätsversuch, siehe oben<br />
SetThreadPriority(GetCurrentThread, oldPriority); // Priorität zurücksetzen<br />
SetPriorityClass(GetCurrentProcess, oldPriorityClass);<br />
*/<br />
}[/cpp]</p>
<p>TDataSafeTest::SaveNewerData wird dann von einer anderen Funktion innerhalb einer for-Schleife aufgerufen.</p>
<p>Das war's erstmal. Ich erwarte ja keine Wunder, aber vielleicht hat ja jemand einen spontanen Einfall...</p>
<p>gruß, oli</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/98457/probleme-mit-shfileoperation-oder-findfirst-findnext-vcl-unter-win2k</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Apr 2026 03:46:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/98457.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 19 Jan 2005 17:42:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Probleme mit SHFileOperation oder FindFirst&#x2F;FindNext (VCL) unter Win2k on Wed, 19 Jan 2005 17:42:53 GMT]]></title><description><![CDATA[<p>hallo!</p>
<p>ich bastele gerade ein programm, das beim runterfahren und hochfahren von windows bestimmte dateien und ordner hin und her kopiert.<br />
ich benutze dafür an der basis die <strong>FindFirst()</strong>- und <strong>FindNext()</strong>-Funktionen und die WinAPI-Funktion <strong>SHFileOperation()</strong>.<br />
Mit <strong>FindFirst()</strong> und <strong>FindNext()</strong> filtere ich rekursiv Dateien raus, die ein bestimmtes Alter überschreiten.</p>
<p>Nun habe ich folgendes Problem:</p>
<p>Beim Sichern der Daten läuft das Programm unter WinXP SP1 &quot;völlig normal&quot;, d.h. die Kopieroperationen mittels <strong>SHFileOperation()</strong> werden in ähnlicher Geschwindigkeit durchgeführt, wie wenn man es von Hand kopieren würde. Unter Win2k allerdings verhält sich das Programm sehr merkwürdig: das Kopieren dauert SUPER lange und wenn ich in den TaskManager gucke wundert mich das auch nicht, denn der Process kriegt einfach keine CPU-Zeit ab, obwohl sonst nichts Großes läuft.</p>
<p>Das Merkwürdige an der Sache ist, dass die <strong>SHFileOperation()</strong> für sich allein gut läuft (unter WinXP und Win2k). Die <strong>FindFirst()-/FindNext()</strong>-Schleifen laufen ohne die Kopieroperation auch einwandfrei (Test über Ausgabe in einem Memo). Nur wenn ich beide zusammenführe, bekomme ich das beschriebene verhalten.</p>
<p>Weiß jemand wieso???</p>
<p>Hier noch ein bisschen Quellcode:</p>
<p>[cpp]// Funktion zum Kopieren/Bewegen von Dateien/Ordnern<br />
// mode = FO_COPY oder FO_MOVE<br />
void __fastcall TDataSafeTest::MyCopy(const CHAR source[MAX_PATH], const CHAR dest[MAX_PATH], int mode)<br />
{<br />
<strong>SHFILEOPSTRUCT fop;</strong><br />
CHAR l_Dest[MAX_PATH];<br />
CHAR l_Source[MAX_PATH];</p>
<p>fill_n(l_Dest, MAX_PATH, '\0');<br />
fill_n(l_Source, MAX_PATH, '\0');</p>
<p>strcpy(l_Dest, dest);<br />
strcpy(l_Source, source);</p>
<p>fop.hwnd = NULL;<br />
fop.wFunc = mode;<br />
fop.pFrom = l_Source;<br />
fop.pTo = l_Dest;<br />
fop.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR; // keine Dialoge anzeigen beim Kopieren<br />
fop.fAnyOperationsAborted = 0;<br />
fop.hNameMappings = NULL;<br />
fop.lpszProgressTitle = NULL;</p>
<p><strong>SHFileOperation( &amp;fop );</strong><br />
}[/cpp]</p>
<p>[cpp]// SaveNewerData speichert eine angegebene Quelle an den angegebenen Zielort,<br />
// wenn die Quelle neuer ist, als das angegebene Datum ( Aufruf von MyCopy() ).<br />
//<br />
void __fastcall TDataSafeTest::SaveNewerData( const CHAR Src[MAX_PATH],<br />
const CHAR Dst[MAX_PATH],<br />
TDateTime TimeOfLastBackup )<br />
{<br />
TSearchRec SR;<br />
CHAR Source[MAX_PATH]; strcpy(Source, Src);<br />
CHAR Dest[MAX_PATH]; strcpy(Dest, Dst);<br />
AnsiString TmpSrc, TmpDest;</p>
<p>/* ein Versuch, die Prozesspriorität hochzusetzen, leider erfolglos<br />
int oldPriorityClass, oldPriority;<br />
oldPriorityClass = GetPriorityClass(GetCurrentProcess);<br />
oldPriority = GetThreadPriority(GetCurrentThread);<br />
SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS);<br />
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_IDLE);<br />
*/</p>
<p><strong>if( FindFirst( AnsiString(Src), faAnyFile, SR ) == 0 )</strong>{</p>
<p>// Unterscheidung zwischen Dateien und Ordnern<br />
if( (SR.Attr &amp; faDirectory) == 0 ){ // es handelt sich um eine Datei</p>
<p>if( FileDateToDateTime(SR.Time) &gt; TimeOfLastBackup ){<br />
TmpDest = AnsiString(Dst)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;<br />
strcpy(Dest, TmpDest.c_str() );<br />
MyCopy( Source, Dest, FO_COPY );<br />
}<br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; ){</p>
<p>// es handelt sich um einen Ordner mit Namen ungleich . und ..<br />
TmpDest = AnsiString(Dest)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>; // neuer Unterordner</p>
<p>ForceDirectories( TmpDest );</p>
<p><strong>if( FindFirst(AnsiString(Src)+&quot;\*&quot;, faAnyFile, SR) == 0 )</strong>{<br />
if( m_LongLog ) LogAddEntry(&quot;FindFirst: &quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>,1);<br />
// es existieren Dateien/Ordner in dem zu kopierenden Ordner<br />
TmpSrc = AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;</p>
<p>if( FileExists(TmpSrc) ){<br />
strcpy(Dest, (TmpDest+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
strcpy(Source, (AnsiString(Source)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
<strong>MyCopy(Source, Dest, FO_COPY);</strong><br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; &amp;&amp; DirectoryExists(TmpSrc) ){<br />
strcpy(Dest, TmpDest.c_str());<br />
strcpy(Source, (AnsiString(Source)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
SaveNewerData(Source, Dest, TimeOfLastBackup);<br />
}<br />
if( m_LongLog ) LogAddEntry(&quot;EndFind&quot;,-1);<br />
}<br />
// durchlaufe alle Einträge in dem angegebenen Ordner rekursiv<br />
<strong>while( FindNext(SR) == 0 )</strong>{<br />
if( m_LongLog ) LogAddEntry(&quot;FindNext: &quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>,1);<br />
TmpSrc = AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>;</p>
<p>if( FileExists(TmpSrc) ){<br />
strcpy(Dest, (TmpDest+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());<br />
strcpy(Source, (AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());</p>
<p><strong>MyCopy(Source, Dest, FO_COPY);</strong><br />
}<br />
else if( <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;.&quot; &amp;&amp; <a href="http://SR.Name" rel="nofollow">SR.Name</a> != &quot;..&quot; &amp;&amp; DirectoryExists(TmpSrc) ){<br />
strcpy(Dest, TmpDest.c_str());<br />
strcpy(Source, (AnsiString(Src)+&quot;\&quot;+<a href="http://SR.Name" rel="nofollow">SR.Name</a>).c_str());</p>
<p>SaveNewerData(Source, Dest, TimeOfLastBackup);<br />
}<br />
}<br />
}<br />
}<br />
FindClose(SR);</p>
<p>/* gehört zum Prioritätsversuch, siehe oben<br />
SetThreadPriority(GetCurrentThread, oldPriority); // Priorität zurücksetzen<br />
SetPriorityClass(GetCurrentProcess, oldPriorityClass);<br />
*/<br />
}[/cpp]</p>
<p>TDataSafeTest::SaveNewerData wird dann von einer anderen Funktion innerhalb einer for-Schleife aufgerufen.</p>
<p>Das war's erstmal. Ich erwarte ja keine Wunder, aber vielleicht hat ja jemand einen spontanen Einfall...</p>
<p>gruß, oli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/700586</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/700586</guid><dc:creator><![CDATA[der oli]]></dc:creator><pubDate>Wed, 19 Jan 2005 17:42:53 GMT</pubDate></item></channel></rss>