繁体   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