|
P/Invoke is used throughout the entire .NET Framework Class Library (FCL). Almost all the Windows Forms controls, for example, "simply" encapsulate the Windows Common Controls. They P/Invoke many native methods, send and handle messages, etc. Many other classes in the FCL P/Invoke native functionality.
Sending input is platform-specific anyway.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hello,
I've developped a Windows Application that needs to know the list of all the files that are opened in all running instances of MSDev (Visual Studio 6.0).
Thanks to Mr H. Stewart I succeeded in getting the files of one instance : the first that has been registered in the ROT (running objects table)... but despite having tried many differents ways, I can't manage to get the files opened in the other instances.
Hereafter is the latest version of my code which uses iteration through UCOMIEnumMoniker and calls UCOMIRunningObjectTable.GetObject for each UCOMIMoniker. Even so, these objects are seemingly all representing the same first MSDev instance...
using Microsoft.Win32;
using DSSharedObjects;
public static string[] ImportFilesFromMSDev()
{
ArrayList AL = new ArrayList();
try
{
object[] Objects = GetActiveObjects("MSDEV.APPLICATION");
foreach( object Obj in Objects )
{
DSSharedObjects.IApplication App = Obj as DSSharedObjects.IApplication;
if ( App==null ) continue;
DSSharedObjects.IDocuments Docs = App.Documents as DSSharedObjects.IDocuments;
if ( Docs!=null && Docs.Count>0 )
foreach ( DSSharedObjects.IGenericDocument D in Docs ) AL.Add(D.FullName);
}
}
catch{}
return AL.ToArray(typeof(string)) as string[];
}
[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out UCOMIRunningObjectTable prot);
[DllImport("ole32.dll")]
private static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc);
private static object[] GetActiveObjects(string ProgId)
{
ArrayList objs = new ArrayList();
UCOMIRunningObjectTable prot;
UCOMIEnumMoniker pMonkEnum;
GetRunningObjectTable(0,out prot);
prot.EnumRunning(out pMonkEnum);
pMonkEnum.Reset();
int fetched;
UCOMIMoniker []pmon = new UCOMIMoniker[1];
while( pMonkEnum.Next(1, pmon, out fetched)==0 )
{
UCOMIBindCtx pCtx;
CreateBindCtx(0, out pCtx);
string str;
pmon[0].GetDisplayName(pCtx,null,out str);
try
{
RegistryKey Clef = Registry.ClassesRoot;
if ( Clef!=null )
{
int P1 = str.IndexOf('{');
int P2 = str.IndexOf('}');
if ( P1>0 && P2>P1 )
{
string ClassHive = @"\CLSID\"+str.Substring(P1,P2);
RegistryKey SK = Clef.OpenSubKey(ClassHive+@"\ProgID", false);
if ( SK!=null )
{
string Val = SK.GetValue("") as string;
if ( Val!=null && ProgId==Val )
{
object objReturnObject;
prot.GetObject(pmon[0],out objReturnObject);
objs.Add(objReturnObject);
}
}
}
}
}
catch {}
}
return objs.ToArray();
}
Any idea ??
Best regards,
- Éric -
|
|
|
|
|
Have you actually tried breaking into your GetActiveObjects method with the debugger and see if the while loop is entered twice? Looking at your code, there's a lot of problems , especially with the way you're using the IBindCtx s. I recommend you read over the COM documentation in the Platform SDK, especially the IBindCtx and IMoniker . Most of your code is just fine, but some of those problems could lead to what you're experiencing.
To note, you will see a CLSID (Item Monikers) for msdev.exe for each instance. You can use irotview.exe in the Common\Tools directory for Visual Studio 6.0.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yes, I've worked with the debugger : the while loop is entered twice (and even one time per MSDev) but it seems that the call prot.GetObject(pmon[0],out objReturnObject) always returns the same object. Therefore I get each time the same list of files.
Well I've already tried to read carefully the COM documentation but I got lost and bogged down in too much detail (in the more so as I'm not so familiar with english).
I'm groping...
If you would mind guiding me a little bit more to get the ActiveObject for each MSDev, it would be very kind of you
What is the right way to use IBindCtx here ?
Kind regards,
- Éric -
|
|
|
|
|
Ah...details: the heart and soul - and bane - of COM programming. It is a wild beast and difficult to tame at times.
When you say you're getting the same object, what exactly do you mean? The Item Moniker will be the same because the same moniker (though referring to different instances) is registered in the ROT. Do you get a duplicate file list or something?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I mean that after calling this method :
object[] GetActiveObjects(string ProgId)
{
while ...
{
prot.GetObject(pmon[0],out objReturnObject);
objs.Add(objReturnObject);
}
}
I get an array of N objects (N=number of MSDev instances) but when casting them into DSSharedObjects.IApplication and asking for the App.Documents I get for each one the same array of files...
Ahhh... (sigh) If only I could get different DSSharedObjects.IApplication objects !
- Éric -
|
|
|
|
|
I'm sorry, but I really don't know what's wrong in that case. Out of curiosity, though, does the documents list for one application object contain a complete list of all documents open in all instances of msdev.exe?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
No, the documents list for one application object contains only the list of the documents open in the first instance of msdev.exe in the ROT. No way to reach others. So it seems that all application objects represent the same one.
So finally all I have is the number of msdev.exe and I can interoperate with only one
I'm sure it's possible... what a pity to be in a deadlock
Anyway, thank you all the same !
- Éric -
|
|
|
|
|
Hi!
I am trying to grasp the usage of SOAP extensions, and was wondering if someone can help me with this scenario:
I have a command line client which invokes a webservice. In response, the webservice is sending some XML which I would like to validate. I understand that in the case where a client _calls_ a webservice, validation can be done in a SOAP extension for the request that is coming to the webservice. The same thing can be done for a request that is outgoing from the webservice.
In my scenario, the called webservice does need to know (or does not care)about validation, it simply sends out the response. I am not sure how I can validate a response from this webservice to my client (at the client side).
Can I use a SoapExtension here? In which case, how would I configure the client so that when it receives a response, the extension is used?
Thanks in advance!
|
|
|
|
|
There are no configuration sections to configure SOAP extensions on the client. Often times you can attribute your proxy methods with SOAP extension attributes to understand the extensions.
You should take a look at Web Service Enhancements 2.0, OR WSE 2.0, that was just released yesterday. These are classes that implement industry standards (like WS Addressing, WS Security, etc.) that make extensive use of SOAP extensions. That should provide quite a bit of insight, especially if you install the SDK and look over the examples.
Otherwise, you're responsible for parsing the SOAP extensions yourself on your client.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How to use this DBNull.IConvertible.ToDecimal Method
|
|
|
|
|
IFormatProvider formatter = CultureInfo.InvariantCulture.NumberFormatInfo;
decimal d = ((IConvertable)DBNull.Value).ToDecimal(null); When you see an explicit interface declaration like that, you must first cast it to the interface; then you can call the explicit interface method implementation (or get/set a property or handle an event).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
But I am getting I dont have reference to assembly...
do i need to include any classes..
Thanks for the immediate reply
|
|
|
|
|
You need to reference all necessary assemblies (in this case, mscorlib.dll which is always referenced unless you tell the compiler otherwise) and import the System namespace:
using System;
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am able to do that...
after that also i am unable to convert DBNull value to decimal...
I have a decimal , if nothing is there in that i need to assign a dbnull value to that , but i am not able to do that
Once again thanks for the immediate response
|
|
|
|
|
Because DBNull.IConvertible.ToDecimal always throws an InvalidCastException . But I answered what you asked.
You might want to be more specific about what you're trying to do. If you need to insert a null value for a decimal field in a database, then you actually use DBNull.Value , not the decimal equivalent (which isn't even possible since value types - such as the primative types - can't be null).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is there anyway i can do that......
|
|
|
|
|
If you use parameterized queryies for example, you could use that as the value:
SqlCommand cmd = sqlConnection1.CreateCommand();
cmd.CommandText = "UPDATE MyTable SET DecimalField = @DecimalField WHERE ID = 1";
SqlParameter decimalField = cmd.Parameters.Add("@DecimalField", SqlDbType.Decimal);
decimalField.Value = myDecimal == 0m ? DBNull.Value : myDecimal;
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Heath Stewart
Could u let me know the solution for this
I have a web page which contains two frames, I am redirecting the user to login page once session timeout, the problem in both the frames I am getting the login page. could anybody let me know how can i handle so that it will redirect to login page with out any frames....
|
|
|
|
|
This is a common problem with frames, which is why almost all web sites do not use them today. I would recommend designing your site using tables to layout your page with included components like headers, footers, and navigation bars.
If you insist on frames, you will have more problems. Make sure you use the target attribute of the A tab wisely.
As far as deirecting a user to a single login page, this isn't possible using the .NET FCL's authentication modules. You would have to write your own authentication module that takes target frames into account. The ASP.NET authentication modules do not do this.
For more information on how to do this, read about IHttpModule and the existing authentication modules like FormsAuthenticationModule to see how they work, even using ildasm.exe that comes with the .NET SDK (if you know how to read IL) or ".NET Reflector", which you can google for (both a disassembler and decompiler with a nice interface - I currently do not have the link available since I'm on vacation).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi
have a problem
Desc:
I am populating a window from parent window, i will perform some action on the child window and i will click OK button, once i click OK i need to pass a server side created object back to parent window.can you let me know how i can do that?
Thanks in advance
|
|
|
|
|
You can't. Once again, HTTP is simple client request/server response. The best you could do is pull the server from the client to watch for changes using the HTTPXML component or the WebService behavior, both supported only by Internet Explorer (Mozilla has a couple of possibilities as well).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Please can you let me know how can i do that? ii have never worked on HTTPXML COMPONENT
|
|
|
|
|
|
Does anyone know how to call an external program in C#?
Thanks,
Tim Cole
|
|
|
|