|
Hi,
when the API expects an array of structs, with unknown array length, one way to get
it working is:
- use IntPtr
- cast it while calling Marshal.PtrToStructure
The following class uses these techniques when calling NetWkstaGetInfo():
#if !NET11 && !NET20
#error "Missing version of .NET Framework (define one of NET11, NET20)"
#endif
using System;
using System.DirectoryServices;
using System.Management;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;
using LP_Core;
namespace LP_Platform {
public class LP_Workgroup {
protected static ILP_Environment env=LP_Environment.GetEnvironment();
protected string name;
public LP_Workgroup() : this(null) {}
public LP_Workgroup(string name) {
if (name==null) {
name="<unknown>";
IntPtr buf;
int result=NetWkstaGetInfo(null, 100, out buf);
env.log(0,"NetWkstaGetInfo result="+result);
if (result==0) {
WKSTA_INFO_100 info=(WKSTA_INFO_100)Marshal.PtrToStructure(buf, typeof(WKSTA_INFO_100));
name=info.wki100_langroup;
env.log(0,"LP_Workgroup: workgroup="+name);
}
if (buf!=IntPtr.Zero) NetApiBufferFree(buf);
result=NetWkstaUserGetInfo(null, 1, out buf);
env.log(0,"NetWkstaUserGetInfo result="+result);
if (result==0) {
WKSTA_USER_INFO_1 info=(WKSTA_USER_INFO_1)Marshal.PtrToStructure(buf, typeof(WKSTA_USER_INFO_1));
string s1=info.wkui1_username;
env.log(0,"LP_Workgroup: username="+s1);
string s2=info.wkui1_logon_domain;
env.log(0,"LP_Workgroup: logon domain="+s2);
string s3=info.wkui1_oth_domains;
env.log(0,"LP_Workgroup: other domains="+s3);
string s4=info.wkui1_logon_server;
env.log(0,"LP_Workgroup: logon server="+s4);
}
if (buf!=IntPtr.Zero) NetApiBufferFree(buf);
}
this.name=name;
}
public string Name {get {return name;}}
public void Scan(LPW_ProgressMessage msg) {
msg.Title="Searching machines in workgroup "+name;
env.alert(msg);
env.outputBegin();
LP_CancellableThread thread=new LP_CancellableThread(msg);
thread.Start(new LP_ObjectHandler(scanner), msg);
}
private void scanner(object arg) {
LPW_ProgressMessage msg=arg as LPW_ProgressMessage;
env.output("Searching machines in workgroup "+name);
DirectoryEntry domainEntry=new DirectoryEntry("WinNT://"+name);
domainEntry.Children.SchemaFilter.Add("computer");
int NAMELEN=0;
foreach(DirectoryEntry machine in domainEntry.Children) {
int i=machine.Name.Length+1;
if (i>NAMELEN) NAMELEN=i;
}
foreach(DirectoryEntry machine in domainEntry.Children) {
msg.Progress(1);
string machineName=machine.Name;
string longname=machineName.PadRight(NAMELEN);
env.log(0,"machineName="+machineName);
IPHostEntry hostEntry=null;
try {
#if NET11
hostEntry=Dns.GetHostByName(machineName);
#elif NET20
hostEntry=Dns.GetHostEntry(machineName);
#endif
} catch(Exception exc) {
env.output(" "+longname+" unable to connect ("+exc.Message+")");
}
if (hostEntry!=null) {
IPAddress[] IPAS=hostEntry.AddressList;
foreach(IPAddress IPA in IPAS) {
msg.Progress(1);
string IP=" IP="+IPA.ToString().PadRight(16);
env.log(0, IP);
byte[] ab=new byte[6];
int len=ab.Length;
byte[] b=IPA.GetAddressBytes();
int IPAadr=(((((b[0]<<8)|b[1])<<8)|b[2])<<8)|b[3];
int r=SendARP(IPAadr, 0, ab, ref len);
string MAC=" MAC="+BitConverter.ToString(ab, 0, 6);
env.log(0, MAC);
env.output(" "+longname+IP+MAC);
longname=" ".PadRight(NAMELEN);
}
}
}
#if true
env.output("All entries");
domainEntry=new DirectoryEntry("WinNT://"+name);
DirectoryEntries children=domainEntry.Children;
foreach(DirectoryEntry entry in domainEntry.Children) {
try {
env.output(" properties of "+entry.Name);
PropertyCollection props=entry.Properties;
foreach(string s in props.PropertyNames) {
object obj=props[s].Value;
env.output(" "+s+"="+obj.ToString());
}
} catch(Exception exc) {
env.output(" Exception: "+exc.Message);
}
}
#endif
aha();
env.outputEnd();
msg.Done(true);
}
public void aha() {
env.output("PRINTERS");
ManagementScope mgmtscope=new ManagementScope(@"\root\cimv2");
mgmtscope.Connect();
ManagementObjectSearcher objsearcher=new ManagementObjectSearcher(
"Select * from Win32_Printer");
foreach(ManagementObject printer in objsearcher.Get()) {
string printername=printer["Name"].ToString();
env.output(" "+printername);
foreach(PropertyData pd in printer.Properties) {
env.output(" "+pd.Name+"="+pd.Value);
}
}
}
[DllImport("Netapi32.dll", ExactSpelling=true)]
public static extern int NetWkstaGetInfo(
string servername,
int level,
out IntPtr buf
);
[DllImport("Netapi32.dll", ExactSpelling=true)]
public static extern int NetWkstaUserGetInfo(
string reserved,
int level,
out IntPtr buf
);
[DllImport("Netapi32.dll", ExactSpelling=true)]
public static extern int NetApiBufferFree(IntPtr buf);
[DllImport("iphlpapi.dll", ExactSpelling=true)]
public static extern int SendARP( int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen);
[StructLayout(LayoutKind.Sequential)]
public struct WKSTA_INFO_100 {
public int wki100_platform_id;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wki100_computername;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wki100_langroup;
public int wki100_ver_major;
public int wki100_ver_minor;
}
[StructLayout(LayoutKind.Sequential)]
public struct WKSTA_USER_INFO_1 {
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wkui1_username;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wkui1_logon_domain;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wkui1_logon_server;
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string wkui1_oth_domains;
}
}
}
|
|
|
|
|
Hi Folks,
I have been a CodeProject Subscriber for a while, and have never needed forum help, But Here goes:
I have been an AMX Netlinx and Crestron Programmer for about 10 years, so I have a vast knowledge of the Proprietery Access, Netlinx, and Simpl+ Programming languages that are very much like C++. I have recently started using another program called StarDraw that the programming language is By-the-Book C#. I am pretty good at assimilating what I know to the C# language, But I am having trouble with some of the syntax and Structure...i.e., I can make controllable actions, but now I am trying to parse text coming back from devices, and wanting to put that text into buffers. I think I need a really good primer or tutorial on C#. Can anyone recommend and good book or a class I can take online to help me along?
Much Thanx,
RedNexHex
|
|
|
|
|
Hope this Link will help you. And there are lot of books are also mentioned there,
Online Tutorials[^]
Regards,
Satips.
|
|
|
|
|
|
hi guys
how can i call a Executable (eg.CMD.EXE) in a way that before the executable starts , Vista will bring up the UAC and ask the user to Cancel or continue or enter password based on their account rights.
i know to run a process, Process.Start() is used, but how can i Demand Administrative rights for that process? thanx
|
|
|
|
|
|
ya runas was what i needed . thanx
|
|
|
|
|
My blocking tcp server looks something like
while (true)
{
recv = ns.Read(message, insertPtr, 1024);
if (recv == 0)
break;
insertPtr += recv;
}
As it is now, the client sends the data(of various sizes) and the client closing the socket when it is done, thus causing ns.Read to return zero.
My question: How can the client get ns.Read to return zero without
closing the socket? I'd like to have the server send some data back to the client without having to open a new socket.
|
|
|
|
|
How to store elemts from generic collection classes to an has table? am not sure about the question, correct me if am wrong.
The problem is, how could i able to know all the elements in TList<employees>?how to access all the elements from that Generic collection class?
|
|
|
|
|
|
If you are not sure about the question how can anyone be sure about what to answer
are you familiar with the 'foreach' keyword?
|
|
|
|
|
Hello everyone,
I have a TEXT file which is holding some data. Can someone be kind enough to tell me how I can empty the text file from all the stored data?
Thank you very much and have a great day.
Khoramdin
|
|
|
|
|
Hi, if no program has the file open you can create (=open for writing) a file with
the same name and close it without writing anything to it, hence replacing the
original with an empty file. You could use the StreamWriter class (with append=false)
and Dispose() the object immediately (i.e. without calling Write/WriteLine).
|
|
|
|
|
You can opent the file for write and use the truncate mode, to make it empty (I think this is default behaviour)
|
|
|
|
|
i want to open Wold file by click button on my application
what the command will help me to do that ???
Palestine
|
|
|
|
|
Hi, all files that, when double clicked in Windows Explorer, cause their
default application to open them, can be opened with that same program programatically
by using Process.Start(document_filename);
|
|
|
|
|
Hello,
I need to send selected items from the ListBox to the database field "keyrings" of datatype varbinary(128),
thelogic i used is to get the selected items from the Listbox and set the byte[] to 1 for the sected item,
//Keyrings
byte[] aGroup = new byte[1024];
string hexString;
for (int index = 0; index < SecurityGroups.Items.Count; index++)
{
if (SecurityGroups.Items[index].Selected)
aGroup[index] = 1;
}
I converted those byte[] to hexstring
hexString = ToString(aGroup);
and then send the value to the database
xmlelem = xmldoc.CreateElement("", "ATTRIBUTE", "");
atttribute = xmldoc.CreateAttribute("NAME");
atttribute.Value = "KeyRings";
xmlelem.SetAttributeNode(atttribute);
xmltext = xmldoc.CreateTextNode(hexString);
xmlelem.AppendChild(xmltext);
xmlelem4.AppendChild(xmlelem);
public static string ToString(byte[] bytes)
{
string hexString = "";
try
{
StringBuilder temp = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
temp.Append(bytes[i].ToString("X2"));
}
hexString = temp.ToString();
}
catch (Exception)
{
}
return hexString;
}
My aGroup array shows first 3 items selected as {1,1,1,0.0.0.0...,
I am having a problem in conversion from bytes to hexstring here...with the first 3 item selected in the listbox, i should get
0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
instead i am getting 01010100000000000000....
Is there any problem with my conversion, Please suggest.
|
|
|
|
|
Hi,
you did a binary string (only 0 and 1 can be present), not a hex string.
And it was too long.
You may try something along these lines:
int count=SecurityGroups.Items.Count;
byte[] aGroup = new byte[(count+7)/8];
for (int index = 0; index < count; index++) {
if (SecurityGroups.Items[index].Selected)
aGroup[index/8] |= 1<<(index%8);
}
if all items were selected, this would or 1 to aGroup[0], then 2 to aGroup[0], then 4,
etc.; then 1 to aGroup[1] and so on, as you probably want.
|
|
|
|
|
Thanks Luc,
but when i run this piece of code.,
i am getting this error
Error 1 Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Is there a way to overcome?
|
|
|
|
|
Sure, this should fix it:
aGroup[index/8] |= (byte)(1<<(index%8));
|
|
|
|
|
Again i am runing into problems.,
I am having difficulties in filling the byte array from the selected items in the listbox,
byte[] aGroup = new byte[1024];
string strKeyRingResXML = "";
string strSecurity = "<security>" + key + "";
string strKeyRingReqXML = "<iacdevrequest>" + strSecurity +
"<requestoperations><dump><options><onlinemode><object id="\""" +
="" stridhi="" +="" "."="" stridlo="" "\"="">";
strKeyRingResXML = ACDev.ProcessRequest(strKeyRingReqXML);
xmlDoc.LoadXml(strKeyRingResXML);
string strAttributesPath = "IACDEVRESPONSE/RESPONSEOPERATIONS/DUMP/OBJECT/ATTRIBUTE[@NAME='KeyRings']";
XmlNode keyringNode = xmlDoc.SelectSingleNode(strAttributesPath);
string keyring = keyringNode.InnerText;
aGroup = GetBytes(keyring);
aGroup contains 100 groups
Here comes the trouble,
I have a list box which filters for the unassignable groups(50-100) for this particular server but my database contains 1000 groups so that the user can see the other 50 or even 100 groups in someother sever.
I need to make changes to the byte array for only those items(from the 50 say i select 5 groups and deselect 2 groups),
for (int index = 0; index < count; index++)
{
if (SecurityGroups.Items[index].Selected)
I need to get the value set for that particular index in the byte array
i tried doing a
aGroup[SecurityGroups.Items[index].Value] = 1;
else
aGroup[SecurityGroups.Items[index].Value] = 0;
but this does not work
}
Can someone please suggest how to go about?
|
|
|
|
|
Hello All,
I have a pdf document that I need to dynamically fill out per peron. It's just a simple 100 entry form that I want to beable to populate and save to pdf from my app. I've done a little searching around and I've seen some various tools and libraries for doing this kind of stuff. I was curious if anyone had any suggestions for a library that I could include in my app that makes it easy to populate existing pdfs with information.
Thanks for the suggestions in advance,
Ryan
|
|
|
|
|
I did a brief search of CP articles and didn't see anything...
Is it possible to get the handle to a differet process/program running? I want to try to make a program that changes programs' opacity, and I thought I'd start by trying to use the two lines:
Form f = Form.FromHandle([some app's handle]);
f.Opacity = 0.5;
I know it looks too easy to work right, and I know it sounds weird, but I want to try it anyway.
-Daniel
Typing too fast fro my owngood
|
|
|
|
|
In your help files look up "Process". You can get a list of running processes that way. And if you already know the name of the process you can also get a list of only those processes with the specified name. From there you can get the process handle and so on.
Phil
|
|
|
|
|
Awesome, thanks!
-Daniel
Typing too fast fro my owngood
|
|
|
|
|