2013-06-28 2 views
0

я следующие 2 набора кода, оба из которых производят одни и те же результаты:Как правильно реализовать inetcpl.cpl как внешнюю dll?

using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace ResetIE 
{ 
    class Program 
    { 
     [DllImport("InetCpl.cpl", SetLastError=true, CharSet=CharSet.Unicode)] 
     public static extern long ClearMyTracksByProcessW(IntPtr hwnd, IntPtr hinst, ref TargetHistory lpszCmdLine, FormWindowState nCmdShow); 

    static void Main(string[] args) 
    { 
     TargetHistory th = TargetHistory.CLEAR_TEMPORARY_INTERNET_FILES; 
     ClearMyTracksByProcessW(Process.GetCurrentProcess().Handle, Marshal.GetHINSTANCE(typeof(Program).Module), ref th, FormWindowState.Maximized); 
     Console.WriteLine("Done."); 
    } 
} 

и ...

static class NativeMethods 
{ 
    [DllImport("kernel32.dll")] 
    public static extern IntPtr LoadLibrary(string dllToLoad); 

    [DllImport("kernel32.dll")] 
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); 

    [DllImport("kernel32.dll")] 
    public static extern bool FreeLibrary(IntPtr hModule); 
} 

public class CallExternalDLL 
{ 
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    public delegate long ClearMyTracksByProcessW(IntPtr hwnd, IntPtr hinst, ref TargetHistory lpszCmdLine, FormWindowState nCmdShow); 

    public static void Clear_IE_Cache() 
    { 
     IntPtr pDll = NativeMethods.LoadLibrary(@"C:\Windows\System32\inetcpl.cpl"); 
     if (pDll == IntPtr.Zero) 
     { 
      Console.WriteLine("An Error has Occurred."); 
     } 

     IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "ClearMyTracksByProcessW"); 
     if (pAddressOfFunctionToCall == IntPtr.Zero) 
     { 
      Console.WriteLine("Function Not Found."); 
     } 

     ClearMyTracksByProcessW cmtbp = (ClearMyTracksByProcessW)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ClearMyTracksByProcessW)); 
     TargetHistory q = TargetHistory.CLEAR_TEMPORARY_INTERNET_FILES; 
     long result = cmtbp(Process.GetCurrentProcess().Handle, Marshal.GetHINSTANCE(typeof(ClearMyTracksByProcessW).Module), ref q, FormWindowState.Normal); 
    } 
} 

оба используют следующие Enum:

public enum TargetHistory 
{ 
    CLEAR_ALL = 0xFF, 
    CLEAR_ALL_WITH_ADDONS = 0x10FF, 
    CLEAR_HISTORY = 0x1, 
    CLEAR_COOKIES = 0x2, 
    CLEAR_TEMPORARY_INTERNET_FILES = 0x8, 
    CLEAR_FORM_DATA = 0x10, 
    CLEAR_PASSWORDS = 0x20 
} 

Оба метода делают это скомпилировать и работать просто отлично, не допуская ошибок, но оба оттока бесконечно никогда не возвращаются из их работы. Код PInvoke был перенесен из следующего VB, который был довольно трудно отследить:

Option Explicit 

Private Enum TargetHistory 
    CLEAR_ALL = &HFF& 
    CLEAR_ALL_WITH_ADDONS = &H10FF& 
    CLEAR_HISTORY = &H1& 
    CLEAR_COOKIES = &H2& 
    CLEAR_TEMPORARY_INTERNET_FILES = &H8& 
    CLEAR_FORM_DATA = &H10& 
    CLEAR_PASSWORDS = &H20& 
End Enum 

Private Declare Function ClearMyTracksByProcessW Lib "InetCpl.cpl" _ 
    (ByVal hwnd As OLE_HANDLE, _ 
    ByVal hinst As OLE_HANDLE, _ 
    ByRef lpszCmdLine As Byte, _ 
    ByVal nCmdShow As VbAppWinStyle) As Long 

Private Sub Command1_Click() 
    Dim b() As Byte 
    Dim o As OptionButton 
    For Each o In Option1 
     If o.Value Then 
      b = o.Tag 
      ClearMyTracksByProcessW Me.hwnd, App.hInstance, b(0), vbNormalFocus 
      Exit For 
     End If 
    Next 
End Sub 

Private Sub Form_Load() 
    Command1.Caption = "削除" 

    Option1(0).Caption = "インターネット一時ファイル" 
    Option1(0).Tag = CStr(CLEAR_TEMPORARY_INTERNET_FILES) 

    Option1(1).Caption = "Cookie" 
    Option1(1).Tag = CStr(CLEAR_COOKIES) 

    Option1(2).Caption = "履歴" 
    Option1(2).Tag = CStr(CLEAR_HISTORY) 

    Option1(3).Caption = "フォーム データ" 
    Option1(3).Tag = CStr(CLEAR_HISTORY) 

    Option1(4).Caption = "パスワード" 
    Option1(4).Tag = CStr(CLEAR_PASSWORDS) 

    Option1(5).Caption = "すべて削除" 
    Option1(5).Tag = CStr(CLEAR_ALL) 

    Option1(2).Value = True 
End Sub 

вопрос просто то, что я делаю не так? Мне нужно очистить интернет-кеш и предпочитаю использовать этот метод, поскольку я знаю, что он делает то, что я хочу, когда он работает (rundll32 inetcpl.cpl, ClearMyTracksByProcess 8 отлично работает). Я пробовал работать как обычный пользователь, так и администратор безрезультатно. Этот проект написан с использованием C# в VS2012 и скомпилирован .NET3.5 (должно оставаться на уровне 3,5 из-за ограничения клиента)

ответ

0

Сигнатуры для rundll32 функции:

void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow); 

Поэтому первая проблема в том, что ваш третий параметр - это перечисление, которое становится целым типом, но вам нужно передать строку. Также обратите внимание, что это LPSTR, а не LPTSTR, поэтому набор символов ANSI, а не Unicode.

Во-вторых, соглашение о вызове stdcall, а не cdecl.

Так что, возможно, что-то больше вдоль линий этого:

[DllImport("InetCpl.cpl", SetLastError = true, CharSet = CharSet.Ansi)] 
private static extern void ClearMyTracksByProcess(IntPtr hwnd, IntPtr hinst, string lpszCmdLine, int nCmdShow); 

Test, который работает здесь, по крайней мере, по мере получения функции для возврата:

class Program 
{ 
    [DllImport("InetCpl.cpl", SetLastError = true, CharSet = CharSet.Ansi)] 
    private static extern void ClearMyTracksByProcessW(IntPtr hwnd, IntPtr hinst, string lpszCmdLine, int nCmdShow); 

    static void Main(string[] args) 
    { 
     ClearMyTracksByProcessW(IntPtr.Zero, IntPtr.Zero, "2", 5); 
    } 
} 
+0

К сожалению, делая эти изменения не делает похоже, имели желаемый эффект. Он все еще сидит и сбивает. (Пробовал это в обоих блоках кода.) – Kyt

+0

Вы также передаете дескриптор процесса для первого аргумента, но ожидается, что будет обработан дескриптор окна. Попробуйте пройти 'IntPtr.Zero'. –

+0

К сожалению, такой же результат. это сумасшествие, чтобы знать, что у меня есть точка входа (кстати, это должно быть ClearMyTracksByProcessW. Я не уверен, почему, но ClearMyTracksByProcess не найден, а W использует Unicode не ANSI), но не может показаться найти правильный синтаксис для вызова. – Kyt

Смежные вопросы