我正在尝试将此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();
}
}
我希望有人可以帮助我
答案 0 :(得分:2)
这是非常可怕的代码,我怀疑CLI / C ++是对的。您应该查找结构的定义,例如
http://msdn.microsoft.com/en-us/library/aa374788(VS.85).aspx
然后在发布前正确清理代码。
我很想在凭证管理中使用this article中的代码
尽管如此,这仍然需要保留你似乎想要摆脱的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);
它不会释放结构等。
答案 1 :(得分:0)
查看pinvoke.net它可能有一个如何调用CredEnumerate的示例