簡體   English   中英

將C ++ / CLI代碼轉換為C#

[英]translating C++/CLI code to C#

我正在嘗試將此c ++ / cli代碼轉換為c#

#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>

   using namespace System;
   using namespace System::Runtime::InteropServices;

    struct CREDENTIAL    
    {
        DWORD Flags;
        DWORD Type;
        LPSTR TargetName;
        LPSTR Comment;
        Runtime::InteropServices::ComTypes::FILETIME LastWritten;        
        DWORD CredentialBlobSize;
        LPBYTE CredentialBlob;
        DWORD Persist;
        DWORD AttributeCount;
        LPBYTE Attributes;
        LPSTR TargetAlias;
        LPWSTR UserName;
    };

    [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet::Unicode)]
    extern BOOL CredEnumerate(LPCTSTR Filter, DWORD Flags, DWORD* count, CREDENTIAL*** Credentials);

    [DllImport("advapi32.dll")]
    extern VOID CredFree(LPVOID);

        int main( array<System::String^>^argv )
        {
            String^ credentialList = "";
            Int32 count = 0;
            CREDENTIAL** credentialCollection = 0;            

            if( CredEnumerate( _T("WindowsLive:name=*"), 0, (DWORD*)&count, &credentialCollection) )                        
            {
                for( Int32 n = 0; n < count; n++ )
                {
                    credentialList += "\n";
                    credentialList += "Username " + gcnew System::String( credentialCollection[n]->UserName ) + "\n";
                    credentialList += "Password: " + gcnew System::String( (LPWSTR)credentialCollection[n]->CredentialBlob ) + "\n";
                } 

                CredFree( &credentialCollection );
        Console::WriteLine(credentialList);

            }
        Console::ReadLine();
        }

這是我的C#代碼..(我不確定CredEnumerate的工作方式)

using System;
using System.Runtime.InteropServices;     // DLL support
using System.Collections.Generic;

public struct CREDENTIAL
{
    public UInt32 flags;
    public UInt32 type;
    public string targetName;
    public string comment;
    public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten;
    public UInt32 credentialBlobSize;
    public IntPtr credentialBlob;
    public UInt32 persist;
    public UInt32 attributeCount;
    public IntPtr credAttribute;
    public string targetAlias;
    public string userName;
}

class Test
{        
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr
    pCredentials);

    static void Main()
    {
        try
        {
            int count = 0;
            IntPtr pCredentials = IntPtr.Zero;
            IntPtr[] credentials = null;
            bool ret = CredEnumerate("WindowsLive:name=*", 0, out count, out pCredentials);
            if (ret != false)
            {

                credentials = new IntPtr[count];
                IntPtr p = pCredentials;
                for (int n = 0; n < count; n++)
                {
                    if (Marshal.SizeOf(p) == 4) //32 bit CLR?
                        p = new IntPtr(p.ToInt32() + n);
                    else
                        p = new IntPtr(p.ToInt64() + n);
                    credentials[n]  = Marshal.ReadIntPtr(p);
                }

                List<CREDENTIAL> creds = new List<CREDENTIAL>(credentials.Length);
                foreach (var ptr in credentials)
                {
                    creds.Add((CREDENTIAL)Marshal.PtrToStructure(ptr, typeof(CREDENTIAL)));
                }

            }
        }
        catch (Exception x)
        {
            Console.WriteLine(x.ToString());
        }

        Console.ReadLine();
    }
}

我希望有一個人可以幫助我

這是非常可怕的代碼,我對CLI / C ++是否正確感到懷疑。 您應該查找結構的定義,例如

http://msdn.microsoft.com/en-us/library/aa374788(VS.85).aspx

然后在發布之前正確清理代碼。

我很想使用本文中有關憑證管理的代碼

盡管如此,這仍然涉及保持您似乎想要擺脫的CLI / C ++,因此我嘗試對其進行修復。

現在,它可以在我的機器上工作了,我已經將它一起入侵了...(注意:我已經刪除了過濾器,以便可以對其進行測試)

[StructLayout(LayoutKind.Sequential)]
internal struct CREDENTIAL {
    public int Flags;
    public int Type;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string TargetName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Comment;
    public long LastWritten;
    public int CredentialBlobSize;
    public IntPtr CredentialBlob;
    public int Persist;
    public int AttributeCount;
    public IntPtr Attributes;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string TargetAlias;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string UserName;
}

然后閱讀

try
{
    uint count;
    IntPtr pCredentials = IntPtr.Zero;
    IntPtr[] credentials;
    bool ret = CredEnumerateW("*", 0, out count, out pCredentials);
    if (ret)
    {
        credentials = new IntPtr[count];
        List<CREDENTIAL> creds = new List<CREDENTIAL>(credentials.Length);
        for(int i = 0; i < count; i++) {
            IntPtr structs= Marshal.ReadIntPtr(pCredentials, IntPtr.Size * i);
            CREDENTIAL c = (CREDENTIAL)Marshal.PtrToStructure(structs, typeof(CREDENTIAL));
            creds.Add(c);
        }
    }
}
catch (Exception x)
{
    Console.WriteLine(x.ToString());
}

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CredEnumerateW(string filter, uint flag, out uint count, out IntPtr pCredentials);

它不會釋放結構等。

看看pinvoke.net可能有一個如何調用CredEnumerate的示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM