Laden...

Forenbeiträge von ymarviny Ingesamt 5 Beiträge

05.02.2010 - 14:25 Uhr

Hallo zusammen,

mit den nachfolgenden Code lese ich den Internet-Cache aus, was auf allen 32-Bit Systemen läuft. Leider wird bei 64-Bit Rechnern nur der Eintrag "lpszLocalFileName" richtig gefüllt, alle anderen Einträge enthalten keine gültigen Einträge.


    [Flags()]
    public enum EntryType
    {
        Unknown = 0,
        Normal = 1,
        Sticky = 4,
        Edited = 8,
        TrackOffline = 16,
        TrackOnline = 32,
        Sparse = 65536,
        Cookie = 1048576,
        UrlHistory = 2097152
    }

    public class IeHistoryEntry
    {
        public string LocalFileName = "";
        public string SourceUrlName = "";
        public string LastAccessDate = "";
        public string HitRate = "";
        public string LastModifiedTime = "";
        public string LastSyncTime = "";
        public string ExpireTime = "";
        public string UseCount = "";
        public string Url = "";
        public string Extension = "";
        public string HeaderInfo = "";
        public string SourceFileName = "";
        public EntryType Type = EntryType.Unknown;
    }

    public class UrlHistroyClass
    {
        //For PInvoke: Contains information about an entry in the Internet cache
        private struct FILETIME
        {
            public int dwLowDateTime;
            public int dwHighDateTime;
        }

        [DllImport("KERNEL32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int FileTimeToSystemTime(ref FILETIME lpFileTime, ref SYSTEMTIME lpSystemTime);

        [DllImport("KERNEL32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int FileTimeToLocalFileTime(ref FILETIME lpFileTime, ref FILETIME lpLocalFileTime);

        private struct SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }

        // For PInvoke: Contains information about an entry in the Internet cache
        [StructLayout(LayoutKind.Explicit, Size = 80)]
        private struct INTERNET_CACHE_ENTRY_INFOA
        {
            [FieldOffset(0)]
            public UInt32 dwStructSize;
            [FieldOffset(4)]
            public IntPtr lpszSourceUrlName;
            [FieldOffset(8)]
            public IntPtr lpszLocalFileName;
            [FieldOffset(12)]
            public UInt32 CacheEntryType;
            [FieldOffset(16)]
            public UInt32 dwUseCount;
            [FieldOffset(20)]
            public UInt32 dwHitRate;
            [FieldOffset(24)]
            public UInt32 dwSizeLow;
            [FieldOffset(28)]
            public UInt32 dwSizeHigh;
            [FieldOffset(32)]
            public FILETIME LastModifiedTime;
            [FieldOffset(40)]
            public FILETIME ExpireTime;
            [FieldOffset(48)]
            public FILETIME LastAccessTime;
            [FieldOffset(56)]
            public FILETIME LastSyncTime;
            [FieldOffset(64)]
            public IntPtr lpHeaderInfo;
            [FieldOffset(68)]
            public UInt32 dwHeaderInfoSize;
            [FieldOffset(72)]
            public IntPtr lpszFileExtension;
            [FieldOffset(76)]
            public UInt32 dwReserved;
            [FieldOffset(76)]
            public UInt32 dwExemptDelta;
        }

        // For PInvoke: Initiates the enumeration of the cache groups in the Internet cache
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "FindFirstUrlCacheGroup",
            CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr FindFirstUrlCacheGroup(
            int dwFlags,
            int dwFilter,
            IntPtr lpSearchCondition,
            int dwSearchCondition,
            ref long lpGroupId,
            IntPtr lpReserved);

        // For PInvoke: Retrieves the next cache group in a cache group enumeration
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "FindNextUrlCacheGroup",
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool FindNextUrlCacheGroup(
            IntPtr hFind,
            ref long lpGroupId,
            IntPtr lpReserved);

        // For PInvoke: Releases the specified GROUPID and any associated state in the cache index file
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "DeleteUrlCacheGroup",
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool DeleteUrlCacheGroup(
            long GroupId,
            int dwFlags,
            IntPtr lpReserved);

        // For PInvoke: Begins the enumeration of the Internet cache
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "FindFirstUrlCacheEntryA",
            CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr FindFirstUrlCacheEntry(
            [MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
            IntPtr lpFirstCacheEntryInfo,
            ref int lpdwFirstCacheEntryInfoBufferSize);

        // For PInvoke: Retrieves the next entry in the Internet cache
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "FindNextUrlCacheEntryA",
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool FindNextUrlCacheEntry(
            IntPtr hFind,
            IntPtr lpNextCacheEntryInfo,
            ref int lpdwNextCacheEntryInfoBufferSize);

        // For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists
        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
            EntryPoint = "DeleteUrlCacheEntryA",
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool DeleteUrlCacheEntry(
            IntPtr lpszUrlName);

        [DllImport(@"wininet",
            SetLastError = true,
            CharSet = CharSet.Auto,
           EntryPoint = "CreateUrlCacheEntryA",
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool CreateUrlCacheEntry(
            string lpszUrlName,
            IntPtr dwExpectedFileSize,
            IntPtr lpszFileExtension,
            string lpszFileName,
            long dwReserved);

        private const int CACHEGROUP_SEARCH_ALL = 0x0;

        private const int ERROR_NO_MORE_ITEMS = 0x103;
        private const int ERROR_CACHE_FIND_FAIL = 0x0;
        private const int ERROR_CACHE_FIND_SUCCESS = 0x1;
        private const int ERROR_FILE_NOT_FOUND = 0x2;
        private const int ERROR_ACCESS_DENIED = 0x5;
        private const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
        private const int MAX_PATH = 0x104;
        private const int MAX_CACHE_ENTRY_INFO_SIZE = 0x1000;

        private const int LMEM_FIXED = 0x0;
        private const int LMEM_ZEROINIT = 0x40;
        private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

        private const long NORMAL_CACHE_ENTRY = 0x200001;
        private const int EDITED_CACHE_ENTRY = 0x8;
        private const int TRACK_OFFLINE_CACHE_ENTRY = 0x10;
        private const int TRACK_ONLINE_CACHE_ENTRY = 0x20;
        private const int STICKY_CACHE_ENTRY = 0x40;
        private const int SPARSE_CACHE_ENTRY = 0x10000;
        private const int COOKIE_CACHE_ENTRY = 0x100000;
        private const int URLHISTORY_CACHE_ENTRY = 0x200000;
        private const long URLCACHE_FIND_DEFAULT_FILTER = NORMAL_CACHE_ENTRY | COOKIE_CACHE_ENTRY | URLHISTORY_CACHE_ENTRY | TRACK_OFFLINE_CACHE_ENTRY | TRACK_ONLINE_CACHE_ENTRY | STICKY_CACHE_ENTRY;


        private DateTime FileTime2SystemTime(ref FILETIME FileT)
        {            
            try
            {
                SYSTEMTIME SysT = new SYSTEMTIME();
                FileTimeToLocalFileTime(ref FileT, ref FileT);
                FileTimeToSystemTime(ref FileT, ref SysT);

                if (SysT.wYear != 0)                    
                    return new DateTime(SysT.wYear, SysT.wMonth, SysT.wDay, SysT.wHour, SysT.wMinute, SysT.wSecond);

                return DateTime.MinValue;
            }
            catch (Exception ex)
            {
                return DateTime.MinValue;
            }
        }

        public Dictionary<string, IeHistoryEntry> GetURLCache()
        {
            try
            {
                // Pointer to a GROUPID variable.
                long groupId = 0;

                // Local variables.
                int cacheEntryInfoBufferSizeInitial = 0;
                int cacheEntryInfoBufferSize = 0;
                bool returnValue = false;

                IntPtr enumHandle = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, IntPtr.Zero, 0, ref groupId, IntPtr.Zero);

                //If there are no items in the Cache, you are finished.

                if ((!enumHandle.Equals(IntPtr.Zero) & ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error())))
                {
                    return null;
                }

                //Loop through Cache Group.

                enumHandle = FindFirstUrlCacheEntry(null, IntPtr.Zero, ref cacheEntryInfoBufferSizeInitial);

                if ((!enumHandle.Equals(IntPtr.Zero) & ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error())))
                {
                    return null;
                }

                cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
                IntPtr cacheEntryInfoBuffer = Marshal.AllocHGlobal(cacheEntryInfoBufferSize);
                enumHandle = FindFirstUrlCacheEntry(null, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial);

                Dictionary<string, IeHistoryEntry> list = new Dictionary<string, IeHistoryEntry>();

                while (true)
                {
                    INTERNET_CACHE_ENTRY_INFOA internetCacheEntry = (INTERNET_CACHE_ENTRY_INFOA)Marshal.PtrToStructure(cacheEntryInfoBuffer, typeof(INTERNET_CACHE_ENTRY_INFOA));
                    cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize;

                    IeHistoryEntry entry = new IeHistoryEntry();

                    entry.LocalFileName = Marshal.PtrToStringAnsi(internetCacheEntry.lpszLocalFileName);
                    entry.SourceUrlName = Marshal.PtrToStringAnsi(internetCacheEntry.lpszSourceUrlName);
                    entry.LastAccessDate = FileTime2SystemTime(ref internetCacheEntry.LastAccessTime).ToString();                   
                    entry.Type = (EntryType)Enum.Parse(typeof(EntryType), internetCacheEntry.CacheEntryType.ToString());
                    entry.Url = Marshal.PtrToStringAnsi(internetCacheEntry.lpszLocalFileName);
                    entry.Extension = Marshal.PtrToStringAnsi(internetCacheEntry.lpszFileExtension);
                    entry.HeaderInfo = Marshal.PtrToStringAnsi(internetCacheEntry.lpHeaderInfo);
                    entry.HitRate = internetCacheEntry.dwHitRate.ToString();
                    entry.LastModifiedTime = FileTime2SystemTime(ref internetCacheEntry.LastModifiedTime).ToString();
                    entry.LastSyncTime = FileTime2SystemTime(ref internetCacheEntry.LastSyncTime).ToString();
                    entry.ExpireTime = FileTime2SystemTime(ref internetCacheEntry.ExpireTime).ToString();
                    entry.UseCount = internetCacheEntry.dwUseCount.ToString();

                    string url = entry.SourceUrlName;

                    int position = url.IndexOf("@");
                    if (position != -1)
                    {

                        url = url.Substring(position + 1);
                        if (url.StartsWith("file:"))
                        {
                            entry.SourceFileName = System.Web.HttpUtility.UrlDecode(url).Substring(8).Replace('/', '\\');
                        }
                    }

                    if (!list.ContainsKey(url))
                        list.Add(url, entry);

                    returnValue = FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial);
                    if (!returnValue & ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error()))
                    {
                        break;
                    }

                    if (!returnValue & cacheEntryInfoBufferSizeInitial > cacheEntryInfoBufferSize)
                    {
                        cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
                        IntPtr tempIntPtr = new IntPtr(cacheEntryInfoBufferSize);
                        cacheEntryInfoBuffer = Marshal.ReAllocHGlobal(cacheEntryInfoBuffer, tempIntPtr);
                        returnValue = FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial);
                    }

                }

                Marshal.FreeHGlobal(cacheEntryInfoBuffer);

                return list;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

Scheinbar stimmen hier die Größennicht, hat damit schon einer Erfahrung und weis wo der Fehler liegen könnte bzw. was geändert werden muss?

Gruß
Frank

08.08.2009 - 19:48 Uhr

Hallo,

es ist ein My-SQL Server, darum verwundert mich ja der Fehler. Wenn es dir hilft kann ich dir gern zum testen die Logindaten zusenden und du kannst versuchen dort was anlegen zu lassen.

Gruß
Frank

07.08.2009 - 21:40 Uhr

Hallo,

ein kleiner Fehler:

erstellt man ein neues Projekt auf einem Server und benutzt dafür ein Unterverzeichnis, wird das sauber erstellt und auch die Dateien werden in das Verzeichnis kopiert.
Beispiel: http:\<Server>\ftpupdare&lt;Projekt1

Im Step "Serverprüfung" wird dann aber als Pfad http:\<Server>&lt;Projekt1> eingetragen und wenn man das nicht gleich sieht und auf "Server prüfen" klickt kommt bei "Prüfe PHP-Version" nur, das er die nicht feststellen konnte.

Kann man liecht drüber stolpern. Wenn man den Pfad dann richtig einträgt geht wieder alles.

Geht man jetzt weiter kommt bei MySQL-Server folgende Fehlermeldung:

Beim Versuch zum angegebene MSSQL-Server zu verbinden ist folgender Fehler aufgetreten:

Es sind mehrere Stammelemete vorhanden. Zeile2, Position 2.

(siehe Anhang)

Leider komme ich jetzt nicht mehr weiter 😦 Passwort und Datenbankname sind richtig. Mit MySQLAdmin komme ich drauf. Die Datenbank ist leer und enthält keine Tabellen

Gruß
Frank

12.06.2009 - 10:30 Uhr

Danke für die Antworten. Ich habe mir mal INotjfyPropertyChanged in der MSDN angeschaut es dann aber dafür nicht verwendet. Habe mir das aber mal gemerkt, kann man sicherlich mal gebrauchen.

Nach den Hinweis von "Mr. Beem" 😉 habe ich folgende Lösung entwickelt:

Beim hinzufügen des Panels speicher ich mir die aktuellen Werte im TAG-Falg ab:


        private void InitPanelForControl(Control ctrl)
        {
            
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                if (ctrl2.DataBindings.Count > 0)
                {
                    string propertyName = ctrl2.DataBindings[0].PropertyName;
                    switch(propertyName)
                    {
                        case "Text":
                            ctrl2.TextChanged += new System.EventHandler(ctrl2_TextChanged);
                            break;
                        case "Checked":
                            break;
                    }
                    ctrl2.Tag = ctrl2.GetType().InvokeMember(propertyName,  BindingFlags.GetProperty, null, ctrl2, null);
                }
                
                InitPanelForControl(ctrl2);
            }
        }

Wird nun ein Wert geändert und anschließend nicht Save/Apply sondern Cancel gedrückt, dann schreibe ich die Werte wieder zurück:


        private void ReloadValues(Control ctrl)
        {
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                for (int l = 0; l < ctrl2.DataBindings.Count; l++)
                {
                    string propertyName = ctrl2.DataBindings[0].PropertyName;
                    ctrl2.GetType().InvokeMember(propertyName, System.Reflection.BindingFlags.SetProperty, null, ctrl2, new object[] { ctrl2.Tag });                                
                }

                ReloadValues(ctrl2);
            }
        }

Das geht zumindest. Danke für die Tipps.

Gruß
Frank

11.06.2009 - 17:03 Uhr

Hallo zusammen,

ich habe ein Problem, was ich nicht schaffe zu lösen. Ich habe in einer extra DLL ein Form erstellt, welches mir die Optionen im Programm anzeigen soll die man dann verändern kann.

Dazu binde ich an das Control jeweils die entsprechenden Einstellungen


txtBackupPfad.DataBindings.Add("Text", setVars, "BackupPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);

Das Form mit dein einzelnen EInstellungen füge ich dann mit


    Panels.Add(new cOptGeneral());

dem Optionsform hinzu und erstelle dabei jeweils einen Menüeintrag für jedes neue Panel.

Jetzt kann ich die Werte ändern und wenn ich das Form verlasse sind die Werte auch in der Variable gesetzt. Jetzt wollte ich aber auch ein "Cancel" einbauen und dachte. wenn ich DataSourceUpdateMode auf Never setzte, kann ich über ReadValue bzw. WriteValue bestimmen ob die Variable gesetzt wird oder nicht.

Leider aber bleibt beim Updatemode "Never" alles leer bzw.ich bekomme es nichthin das der Wert im Steuerelement nicht gleich automatisch auf dem Wert der Datenbindung übertragen wird.

Ich habe schon mit "OnValidation", "OnPropertyChanged" und "Never" einiges probiert...

Anbei noch mal Code zum Verständis:

Im Hauptprogramm

  1. frmOptions.cs
    Zeigt die Einstellungen an. Hier werden nur die einzelnen Einstellungsübersichten hinzugefügt.

    Panels.Add(new cOptGeneral());
    Panels.Add(new cOptFolder());

  1. cOptFolder
    Für jede Einstellungsgruppe gibt es ein Control

            txtBackupPfad.DataBindings.Add("Text", setVars, "BackupPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);
            txtHistoryPfad.DataBindings.Add("Text", setVars, "HistoryPfad", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged);

  1. Eine extra DLL übernimmt die Anzeige und Aktualisierung. Hier wollte ich dann bei Canzel die Werte zurücksetzen

        private void ReloadValues(Control ctrl)
        {
            for (int i = 0; i < ctrl.Controls.Count; i++)
            {
                Control ctrl2 = ctrl.Controls[i];

                for (int l = 0; l < ctrl2.DataBindings.Count; l++)
                {
                    Binding bind = ctrl2.DataBindings[l];
                    bind.ReadValue();
                }

                ReloadValues(ctrl2);
            }
        }

Oder sollte man das ganz anders machen? Aber eine andere tolle Idee habe ich dafür noch nicht gefunden.

Gruß
Frank