|
InstallUtil does complain about missing public installers but this is automatically generated code!
InstallUtil log file
"No public installers with the RunInstallerAttribute.Yes attribute could be found in the c:\...\visual studio projects\windowsservice1 \bin\debug\windowsservice1.exe assembly.
Remove InstallState file because there are no installers."
But...
The code generated by C# automatically puts [RunInstaller(true)] not [RunInstallerAttribute], is this a bug? I am using .Net 2003.
This is the code generated by C#
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
public System.ServiceProcess.ServiceInstaller serviceInstaller1;
private System.ComponentModel.Container components = null;
public ProjectInstaller()
{
// This call is required by the Designer.
InitializeComponent();
}
...
private InitializeComponent()
{
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account =
System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.DisplayName = "A Windows Service";
this.serviceInstaller1.ServiceName = "Service1";
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[]
{ this.serviceProcessInstaller1, this.serviceInstaller1
}
);
Guillermo Jimenez
|
|
|
|
|
In C#, "Attribute" is not required for classes that end in "Attribute" and that derive form Attribute . This is documented.
I do see a problem even with the auto-generated code - namely the properties that you filled-in, or rather didn't fill in. If you read the documentation for the ServiceInstaller.ServiceName property, it is crucial that your ServiceBase.ServiceName (ServiceBase is what you extended, of course) and your ServiceInstaller.ServiceName match exactly. I'm hoping you didn't call your Windows Server "Service1" (the name that you pass to net start or net stop). You need to disambiguate and give it something meaningful (like w3svc for the HTTP service in Windows NT, or iisadmin for the IIS Administration Service).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
Generic method for accessing fields in C# classes/structs
==========================================================
Previously in the unmanaged C++ world, a client could declare a structure of any length, cast it to a VOID pointer to memory, and then just deal with it as a memory location. This is sort of a rough and tumble version of polymorphism.
Consider the following example in unmanaged C++:
Client code:
===========
typedef struct dimStruct
{
double x;
double y;
int location;
};
SumFunc()
{
int aFields[] = { X_DIM, Y_DIM, LOCATION };
int iNumberItems = 3;
dimStruct dims;
services->FillTheStruct( (PVOID)&dims, aFields, iNumberItems );
}
Services Code
=============
Services::FillTheStruct( PVOID pData, int aFields[], int iNumberItems )
{
//** Now loop through the field array and stuff values into the
//** correct offsets in memory.
int itemOffset = 0;
for ( int I =0; I < iNumberItems; i++ )
{
int sizeOfItem = GoGetDataItem( &pData[itemOffset], aFields[i] );
//** increment the offset within the pData memory block
itemOffset += sizeOfItem;
}
}
I was able to replicate the functionality in C# (close. but not quite) through the following:
Client Code
===========
object[] aObjects = new object[3];
aObjects[1] = dimStruct.x; //** double
aObjects[2] = dimStruct.y; //** double
aObjects[3] = dimStruct.location; //** int
services->FillTheStruct( aObjects, aFields );
dimStruct.x = aObjects[1]; //** double
dimStruct.y = aObjects[2] //** double
dimStruct.location = aObjects[3] //** int
ServicesCode
============
FillTheStruct( object[] aObjects, int[] aFields )
{
//** Get the array of types
Type aType[] aTypes = type.GetTypeArray( aObjects );
int iSize = 0;
//** Figure out the size (to simplfy examples, ignore strings)
foreach ( Type oneType in aType )
{
iSize += marshal.SizeOf( oneType );
}
byte[] aBytes = new byte[ iSize ];
//** Magically stuff data into byte array
Services->FillTheStruct( aBytes, aFields );
//** Now, fill the client’s aObject
MemoryStream stream = new MemoryStream( aBytes );
BinaryReader reader = new BinaryReader( stream );
int iFieldCount = aObjects.GetLength( 0 );
for ( int index =0; index < iFieldCount; index++ )
{
Type oneType = aTypes[ index ];
If ( oneType.Equals( typeof( double )))
{
aObjects[ index ] = reader.ReadDouble();
}
else if ( oneType.Equals( typeof( int )))
{
aObjects[ index ] = (int)reader.ReadInt32()
}
//** And so on….
}
}
So the questions are:
====================
Is it possible to replicate the original solution in C# without using an object[] array as an intermediary?
Is there a generic way to walk through an unknown class/struct, get the fields, their types, and then make assignments into that structure/class?
I would have to have a method that accepts some sort of generic object to start.
Thanks in advance,
JohnB
|
|
|
|
|
I think you could use the GetType method to get the type of the object, which can be used to extract the properties it has and such, using the Type objects methods.
you could set the variables data using Marshal.StructureToPtr to put the structure into an IntPtr, which where you will be able to write bytes to specific using the Marshal classes methods.
|
|
|
|
|
You can still do that using C# in .NET, but I don't recommend it. You can use an unsafe code block. When you use unsafe code, though, it is not managed and you lose the benefit of a managed environment (plus it requires more permissions granted to your object; a problem if you're not running from the local machine (by default)).
Serialization - which you're currently doing yourself - is the best way to handle this. Not only is it extensible, but it's fairly straight forward to use and safe. Define your struct as [Serializable] (not inheritted) and change FillStruct like so:
[Serializable]
public struct Dim
{
public long field1;
public int field2;
public string field3;
}
public void FillStruct(out Dim dim)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(BitConverter.GetBytes(0L), 0, 8);
ms.Write(BitConverter.GetBytes(0), 0, 4);
byte[] buf = Encoding.ANSI.GetBytes("Test");
ms.Write(buf, 0, buf.Length);
ms.Seek(0, SeekOrigin.Begin);
BinaryFormatter formatter = new BinaryFormatter();
dim = (Dim)formatter.Deserialize(ms);
}
} Serialization is very powerful and quite easy to use in the .NET Framework. I encourage you to read Serializing Objects[^] in the .NET Framework SDK, which discusses both runtime serialization (what I described above), and XML serialization.
You could also use the Marshal class, which can help you do this, too, but relies on unsafe code as well (but it's defined in mscorlib.dll, which must have FullTrust permissions - it's the core assembly of the .NET BCL and practically impossible to do without when targetting the CLR).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
johnbMA wrote:
Is there a generic way to walk through an unknown class/struct, get the fields, their types, and then make assignments into that structure/class?
Sure, something like the following (obviously you will want to do further error checking but this should get you started):
Assembly a = Assembly.LoadFile(@"C:\somedir\dir\some.dll");
if(a != null)
{
Type[] types = a.GetTypes();
foreach(Type t in types)
{
PropertyInfo[] pia = t.GetProperties();
MethodInfo[] mia = t.GetMethods();
FieldInfo[] fia = t.GetFields();
ConstructorInfo[] cia = t.GetConstructors();
EventInfo[] eia = t.GetEvents();
Type[] ia = t.GetInterfaces();
}
}
- Nick Parker My Blog | My Articles
|
|
|
|
|
Hello,
Is there a max length of text that can be shown in the statusbar?
I can only get it to hold 127 characters in the statusbar or in a statusbar panel.
Blake
|
|
|
|
|
Nevermind, I found the answer. Guess I'll have to use a custom statusbar component or make my own.
|
|
|
|
|
When you find answers to your own questions, please post them here. The forum is here to help the community; had anyone else replied you should've been provided the answer.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
The statusbar only displays the first 127 characters of the text string. To get around this, I made an owner-drawn panel, and used DrawString to draw the text.
|
|
|
|
|
Hi there, again...
Now I have here a little problem.
I was searching on the net, and I discovered an algorithim to detect scene changes with the histogram method. The method is something like this:
A - histogram of the first frame (an array of 255)
B - histogram of the second frame (an array of 255)
If A - B > thershold it is a scene change, If A - B < thershold it isn´t.
My problem is, I have to Bitmaps with the frames, how can I read the bitmap values to the two arrays that I have created?!!
Sorry, this is a newbie doubt, but I don´t know how I do this =/
Thanks, Sérgio
|
|
|
|
|
What values do you mean, exactly? If you want to read the pixels in, the easiest and safest way is using Bitmap.LockBits , enumerate the scan lines and pixels returned in the BitmapData (return value for LockBits ), and then call Bitmap.UnlockBits passing the BitmapData back. I say safest because you can do this a little faster using unsafe code (i.e., direct memory access using pointer math).
For an example, read Christian Graus's Image Processing for Dummies with C# and GDI+ Part 1 - Per Pixel Filters[^].
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
Thanks very muck, I already know what I have to do.
YOur help was very useful
|
|
|
|
|
Hi,
Have you been able to do a scene change detection in C#? I am currently breaking my head, trying to develop a scene change detection component, which will give me the frames of a video, where a scene change is detected.
Can you help me on this? Can you please contact me at manajit(at)yahoo.com
Regards,
Manajit.
|
|
|
|
|
This is the API I want to use:
long LoginDlg<br />
(<br />
long lDSType,<br />
LPTSTR lptstrDataSource, <br />
long lDSLength,<br />
LPCTSTR lpctstrUsername, <br />
LPCTSTR lpctstrPassword,<br />
)
I wrap it like this:
[DllImport("user.dll")]
int LoginDlg<br />
(<br />
int lDSType,<br />
stringlptstrDataSource, <br />
int lDSLength,<br />
stringlpctstrUsername, <br />
stringlpctstrPassword,<br />
)
Now I got the new version of this api, the only difference is using LPWSTR instead of LPTSTR
long LoginDlg<br />
(<br />
long lDSType,<br />
LPWSTR lptstrDataSource, <br />
long lDSLength,<br />
LPCWSTR lpctstrUsername, <br />
LPCWSTR lpctstrPassword,<br />
)
I use the same wrapper, it doesn't work as usual. Do you have any ideas what's wrong with my wrapper?
Thanks in advance.
|
|
|
|
|
First, understand how the unmanaged code (i.e., native code) looks (essentially):
typedef char CHAR;
typedef CHAR* LPSTR;
typedef wchar_t WCHAR;
typedef WCHAR* LPWSTR;
#ifdef UNICODE
typedef WCHAR TCHAR;
typedef WCHAR* LPTSTR;
#else
typedef CHAR TCHAR;
typedef CHAR* LPSTR;
#endif That means that any Unicode strings use "W" as a convention (this is true with most Microsoft APIs - as well as others' APIs - that take strings as parameters; they end with either "A" for ANSI or "W" for Unicode and are #define'd without either "A" or "W", which is the one you typically call).
When you use P/Invoke or COM interop (both are interop features), you must dictate which string encoding to use. By default in C#, CharSet.Ansi is used. In most cases when calling Microsoft APIs (and others - those I mentioned above), you will want to use CharSet.Auto . Where do you use those?
When declaring P/Invoke methods, you use them in the DllImportAttribute like so:
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern bool GetComputerName([Out] string name, ref int size); When you're declaring a struct with string members, you do the same in the StructLayoutAttribute .
In both cases, you can override the string encoding using the MarshalAsAttribute .
Lets say, for some reason, you had a struct with ANSI and Unicode versions, except for one string member that must always be ANSI:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct Example
{
public string Field1;
public string Field2;
[MarshalAs(UnmanagedType.LPStr)] public string Field3;
} We default to CharSet.Auto (saves typing and is easier to maintain) but override the unmanaged type as UnmanagedType.LPStr (as opposed to UnmanagedType.LPWStr ), so that it's always ANSI. You can do the same with P/Invoke declarations.
Just make sure you understand the unmanaged code well enough to know whether it's always ANSI or Unicode, or if it is platform dependent (i.e., ANSI on Windows, Unicode on Windows NT).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
According to my understanding, the new method is using Unicode all the time. So I wrap it like this now:
[DllImport("user.dll", CharSet = CharSet.Unicode)] <br />
int LoginDlg<br />
(<br />
int lDSType,<br />
string lptstrDataSource, <br />
int lDSLength,<br />
string lpctstrUsername, <br />
string lpctstrPassword,<br />
)
But why it still doesn't work?
|
|
|
|
|
Since the function is defined externally, you have to modify it as such, and all P/Invoke functions are static (i.e., they aren't defined by a class). Your signature should look like this:
[DllImport("user.dll", CharSet=CharSet.Unicode)]
extern static int LoginDlg(
int lDSType,
string lptstrDataSource,
int lDSLength,
string lpctstrUsername,
string lpctstrPassword); Drop the comma after lpctstrPassowrd and add a semi-colon after the declaration, as well.
BTW, since the parameter names begin with either lptstr or lpctstr , they are most likely using platform-dependent string encodings. You best check your API documentation and thoroughly examine your headers. Using "t" typically means that a string is platform dependent, although thiscould be just a different naming convention for your APIs. If these are Microsoft APIs, I assure you they're platform-dependent strings and you should use CharSet.Auto .
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
Then write up an article on it. If you post it here, your answer will disappear into the "forum oblivion" in about a day...
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
hi,
You wrote :
I am bangin my head against the
What you mean by this post ?
**************************
S r e e j i t h N a i r
**************************
|
|
|
|
|
What is your question? If you need help regarding string searches and other string manipulation, you should read the String class[^] documentation in the .NET Framework SDK.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles]
|
|
|
|
|
I am banging my head against the wall on this one:
i am attempting to do a comparison between 2 strings. what i am attempting to do is this
I have strings String #1 and String #2.
I have turned string #1 into an array, and what i want to do is
foreach (string arrayvalue in array)<br />
{<br />
if (arrayvalue exists in string #2)<br />
{<br />
blah blah blah<br />
}<br />
else<br />
{<br />
blah blah<br />
}<br />
}<br />
I know how to do a wildcard search in a rowfilter, but unfortunately that code does nto seem to translate directly into the above format. Any ideas?
Yes, I am the highly suggestable type.
|
|
|
|
|
hi,
Here the senario is you want to check whether any of the string which is there in your first array exists on second array.
upto my level best i didn't found any keyword 'exists' in C#.
You can do this logic insted of your logic.
foreach(string Str in ab)
{
foreach(string Str2 in bc)
{
if(Str.Equals(Str2))
Console.WriteLine("String Found");
else
continue;
}
}
**************************
S r e e j i t h N a i r
**************************
|
|
|
|
|
Thanks for the reply. i had done something very similar to this previously (i did if( Str == Str2) in the same format. what happens, though is that if you have 4 objects in each array, it returns 16 results, 3/4 12, etc. what i am attempting to do is a comaprison of the two, and for any matches, print "yes", and for any that are in one strin but not the other, print "no". for example:
string 1 is red*blue*yellow*green*black
string 2 is green*red*blue*pink
the results i am looking for are
red = yes
green = yes
blue = yes
pink = no
black = no
in regards to your other post, i hit the tab key when typing the original message and accidentally made a gibberish post.
Yes, I am the highly suggestable type.
|
|
|
|
|
hi,
I gave the idea and now you are asking for logic. We won't encourage developers by giving logic. It is upto you to structure your program to get required result.
Apart from that i don't have enough time to sit and code for you. But Still if i get time i will do that. Ok.
**************************
S r e e j i t h N a i r
**************************
|
|
|
|
|