|
Great link, thanks.
-Nick Parker
|
|
|
|
|
|
WiB wrote:
How to pass arguments in OnStart method of service?
Service supposed to start automatically at a boot time.
There is no way to pass arguments to a service at boot time, that is because the Windows API CreateService does not take any "default" argument. However, if you can create a service that is not started automatically at boot time and create a second service whose job is to start the first service at boot time, then you can pass arguments to the first service (using the StartService API).
<Edit>It is probably easier to</Edit> do it (the second service) in C/C++, by the way. If you don't want to bother writing a service in C/C++, you can use XYNTService[^] to start your service, passing any argument you want from the "command line" defined in the .ini file.
Click here to see my articles and software tools
|
|
|
|
|
WiB wrote:
If I have an .INI file with arguments I can read this .INI file in OnStart method of service and I don't need to create second service, do I?
Yes, if you are satisfied with reading data from a file, then you don't really need to pass any argument. The second service makes it possible to pass arguments through command line at boot time.
WiB wrote:
In C# there is ServiceController class that controls services. What's the problem to create second service in C#?
No problem, I should have said "it is probably easier to ..."
Click here to see my articles and software tools
|
|
|
|
|
WiB wrote:
If I start second service by calling StartService from first service, how do I pass arguments in service?
The StartService API can take arguments for the service to be started, if a service calls StartService to start another service, the arguments will be passed to the other service as if you have typed them from the command line. Of course, you have to get the arguments from within the first service. You don't need to do much when using a tool like XYNTService.
Here is how to use XYNTService to do what you need:
a) Copy XYNTService.exe to your local machine and install it with the following command:
<br />
XYNTService.exe -i<br />
b) Save the following text as file XYNTService.ini in the same folder:
<br />
[Settings]<br />
ProcCount = 1<br />
[Process0]<br />
CommandLine = c:\MyDir\XYNTService.exe -r MyService Arg1 Arg2 Arg3<br />
c) Reboot the machine.
When the machine is started, XYNTService will execute commands defined in the XYNTService.ini file, in this case, the command is
<br />
XYNTService.exe -r MyService Arg1 Arg2 Arg3<br />
The above command will call StartService passing Arg1, Arg2, and Arg3 to the service named MyService, MyService must not auto start at boot time. To stop your service from the command line, use the following
<br />
XYNTService.exe -k MyService<br />
Hope this helps.
Click here to see my articles and software tools
|
|
|
|
|
WiB wrote:
I took a look on your code.
For example, I create the service passing the following string as the lpBinaryPathName parameter of CreateService():
"d:\\foo\\foo.exe param1 param2"
I suppose that in main(int argc, char *argv[])
argc will be 2
argv[0] will be param1
argv[1] will be param2
Can you tell me if it's correct?
I don't think it will work that way. You will probably get a "file not found" or "invalid path" error. The lpBinaryPathName parameter does not contain arguments. Read my other reply on how to get around this.
Click here to see my articles and software tools
|
|
|
|
|
|
WiB wrote:
Yes, it's true, it works!
Ok, good for you! Just one more twist, if you pass the arguments at CreateService time, how do you change them later? You will have to call a service api (or use ServiceController class) to do that. Of course, you can always uninstall the service and reinstall it with different arguments.
<Edit>I still think using XYNTService is a better way, you don't even need to write your own service, you can do what you want in a regular and simpler program and start the program with XYNTService.</Edit>
Click here to see my articles and software tools
|
|
|
|
|
No, argc is 3 and argv[0] is actually the application name. argv[1] and argv[2] are param1 and param2, respectively. As a side note, .NET does not pass the application as the first argument. Some languages do, some languages don't.
Besides, parameters aren't passed to the Windows Service in the entry point (commonly referred to as main ). In .NET, these are passed in OnStart(string[] args) .
If I were you, just read settings from the app's config file (named MyServer.exe.config - just append ".config" to your service application and put them in the same directory). You could write your own IConfigurationSectionHandler , or just use the provided <appSettings> , which gives you a simple key-value pair. It's just an XML file so it's easy to edit (both manually and programmatically).
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Parameters are not passed to Windows Services through Main ! Read the documentation - it states this clearly. They are passed from the SCM to .NET's virtual OnStart(string[] args) method. The main method is only the entry point for the executable. If you want to pass parameters to your service, you set these in the server control manager (the Services MMC snap-in, for example, allows you to do this).
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
But did the SCM pass the parameters, or did you when you executed the EXE? You're supposed to override OnStart . RTFD!
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Parameters are not stored in the registry - registry keys are stored in the registry. Parameters and settings are not the same thing. Yes, you can - in Main - query the registry for settings, but parameters are passed TO main, and only the executable loader does that, beings that it's the entry point and not just a function (at least when the executable is loading).
There is nothing wrong with storing settings in the registry and reading them from the registry in Main, but it is recommended (RTFD!) to do everything in OnStart . This follows the .NET model of OOP since the entry point doesn't necessarily have to be in the ServiceBase -derived class. It could be anywhere. The SCM doesn't use the entry point at all - the executable loader does. The ServiceBase class is a wrapper of sorts that the SCM does - indirectly - use. This is the point I've been trying to make. You do know what RTFD means, right? It's all in there, both in the .NET documentation and a lot in the Platform SDK for Win32. You shouldn't rely on the entry point (Main in C#, for example).
So, read your settings from the registry or from the .NET config file (which is preferred over the registry for .NET applications for many reasons), or from a database or INI file - it doesn't matter! Just don't confuse parameters with settings and make sure you know how the SCM passes parameters.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Yes, when you call the executable with command line parameters, the parameters are passed to the main method. How many times do I have to say that the SCM (which merely invokes executables, but the command-line in the SCM is not passed to the application's entry point method (ex, main). The executable loader on the system passes params to the entry point method, which is what you're doing. Either way is fine, but the SCM is not passing these params - the executable loader is. I am making a point here - not saying which way is right or wrong - and you don't seem to be getting that.
The only thing that is wrong with what you're doing is that it's a lot easier to change a single registry parameters than to read-in the command-line for your service (because you should never assume the user took the default path or didn't change the location), change the parameters in the executable (which can be difficult to parse at times), then write it back out to the registry. Reading values from the registry or, better yet, a config file is much easier to manage and easier for users to change (the registry keys for a service are deep and often hard to find since you have to know the actual service name, not the display name of the service - unless you do an exhaustive find).
If you don't get the point I'm trying to make, then I'm sorry - you don't understand how executables are loaded on a system and how the SCM interacts with the service which all comes down to Win32 calls, which you obviously don't understand either. If you don't want to take the time to learn, then do it however you want and be completely ignorant about what is actually happening in the background.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Heath Stewart wrote:
How many times do I have to say that the SCM (which merely invokes executables, but the command-line in the SCM is not passed to the application's entry point method (ex, main).
In this case how should I understand these lines from MSDN:
"Sometimes an auto-started service may want to receive arguments. Unfortunately, there is no method to pass arguments to a service through it's Service_Main(). These arguments can only be passed to a service through it's main(). (This entry point is defined by the user via the compiler. The default entry point is named main().) You can setup the arguments when you install the service through the CreateService API. For example, to pass the arguments "franki" and "hosun" to an auto-started service, you would pass the following string as the lpBinaryPathName parameter of CreateService():
"d:\\foo\\foo.exe franki hosun"
When the service starts, it can obtain these arguments via its main() through argc and argv. "
|
|
|
|
|
God, I'm hoping some of you can help me here. I need DIRECTION.
I want to create a .NET application. I want to use C# language since it seems good for rapid application development.
I want to create the user interface (GUI) using the Visual Studio IDE form design.
Tell me if the following is possible:
I want to use DirectShow AND the Microsoft Speech .NET SDK in the SAME application. How can I do this? All the DirectShow examples are written in C++. All the .NET speech examples are written in C#.
Can I write the bulk of my application in C# and use C++ only for the DirectShow portion of it? Is this possible too?
Also, I'd like to "skin" my application, or in the very least give it some "personality" with rounded buttons and some custom controls that I create myself. Can I still use the Win32 API and "layered" windows to skin a GUI created with the "forms" wizard in Visual Studio? Is there any other way of creating that "custom" look?
I'm new to this stuff and I'm really confused. What's worse, is that I read all kinds of stuff about "managed code" and how DirectShow does not use managed code... DirectShow is built upon COM objects.... .NET allows one to mix managed and unmanaged code in the same application.... blah blah blah.... HELP!!!
All I want is some direction and advice on what to do 1st, 2nd, 3rd... I just don't know where to start... I don't want to read a 400 page book on ATL and COM if I'll be using C# which hides the COM internals... you know what I mean? HELP!!!
|
|
|
|
|
I don't think you get .NET - the language doesn't matter! The classes, methods, properties, structures, etc. are the same for any language that uses the .NET class library and targets the CLR. The only differences between languages is the syntax itself. Just translate and use the managed assemblies for .NET from the SDK.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Uhh... I don't think you get my questions!
All the DirectShow stuff is written in UNMANAGED C++ code. Bang! Problem #1 there. There is NO .NET equivalent for DirectShow stuff.
I found someone on the net who has created TYPE LIBRARIES that I can use within C# to access the DirectShow COM objects.
Guess I answered my own question. I'll have to mix managed code (.NET) with legacy code (unmanaged stuff).
Regards,
Brian
|
|
|
|
|
That will work just fine. Remember that the the .NET BCL is built on the Windows API.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Does anyone know how to use the following type library I found for DirectShow?
http://www.kohsuke.org/dotnet/directshowTypelib/
Does this type library have anything to do with C++ wrapper classes?
Like I said before.... I'm a beginner... it's unreal just how complicated programming has become since I programmed in C eons ago.
I'm looking for Step#1, Step#2, Step#3.... you get the point...
I'm working in Visual Studio 2003, BTW.
Thanks!
Brian
|
|
|
|
|
Just add a reference to them in your project, and use the classes/interfaces in them just as the documentation states - just the way you'd use the COM DirectShow stuff from C++, except in C#.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Thank you very much, Jdunlap, for your assistance....
BTW, I like your signature, "You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Brian JR wrote:
Thank you very much, Jdunlap, for your assistance....
You're welcome.
Brian JR wrote:
BTW, I like your signature, "You must be the change you wish to see in the world." - Mahatma Gandhi
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
|
Okay, I did not realize that DirectShow was not part of the SDK. To be honest, I hadn't had a chance to dig in it much yet even though I installed it way back when 9.0 was released ( no time )
However, you don't need to use mix mode. If someone has created a typelib, just create an interop assembly (either using VS.NET or the tlbimp.exe utility, part of the .NET Framework SDK) and use the assembly like any other. This way, you can keep it all in C# and not mess with mixed mode in MC++.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
Oh God... thanks so much.... I just want to decide on a method.... because there are so many.... one method is to use this "type library"... another method is to write "wrapper classes"....
Here's the type library that I found:
http://www.kohsuke.org/dotnet/directshowTypelib/
I imported the *.dll file as an additional reference into my project. At that point I could examine the objects contained within. Is this what you mean?
What is an interop assembly? All I have is a *.tlb and a *.dll file from that link above. How are these related to interop?
Brian
|
|
|
|
|
You don't actually need the TLB file. The DLL is a .NET assembly that contains classes, methods, propertie, structs, enums, etc. that interoperate (interop) with COM. These DLLs do not contain the implementation, though, just as the TLBs don't. So you still need DirectShow installed on a user's computer. The CLR will create a Runtime Callable Wrapper (RCW) around the DirectShow COM controls automatically when you use the classes just like any other .NET classes from the BCL (or other libraries). Just use the DLL like any other assembly and don't worry about the details - the CLR does this for you. Reading about them is educational and is something you should do if you want to understand (and even good developer should understand what they're getting into).
Similarily, .NET controls can be exposed to COM through interop. In this case, the CLR creates a COM Callable Wrapper (CCW) around the .NET object so that it looks like a COM object. Nick Parker has a great article on CP about it, and I have one that goes into more details, even into bridging Java and .NET together with C++ using COM and JNI. It gives some in-depth details, but Nick's is better for understanding the concepts (make sure you read the comments, though, there was a few things I added to the article).
There's some good information about this on MSDN as well.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|