c++ objects, I don't get it - IIS ADSI object
-
I'm not a c++ programmer, but I need to be. I wrote a dll for installshield, that installs the web server program using shell as a custom action, but when I use their (IISHelper.dll) dll for programming the website, I run into problems. Thus I should write my own stuff in the same custom action. So I working with some sample code, that gets the object, but the sample code returns the HRESULT, and not the object, unless the object is IIS_IADs, like getting the value of a registry key?, in which it's there but you have to sort of dig it out. For now, I want to grab the default website in IIS5.1, and change the virtual path, the path to the code, and set the documents, mimes and so forth. If I can figure out how to grab the master object, I think I can program the rest and write the values.
hr = ADsGetObject( L"IIS://localhost/w3svc/1/root", IID_IADs, (void **)&pADs );
if ( FAILED( hr ) ) {
app_Level = 1;
goto error;
} -
I'm not a c++ programmer, but I need to be. I wrote a dll for installshield, that installs the web server program using shell as a custom action, but when I use their (IISHelper.dll) dll for programming the website, I run into problems. Thus I should write my own stuff in the same custom action. So I working with some sample code, that gets the object, but the sample code returns the HRESULT, and not the object, unless the object is IIS_IADs, like getting the value of a registry key?, in which it's there but you have to sort of dig it out. For now, I want to grab the default website in IIS5.1, and change the virtual path, the path to the code, and set the documents, mimes and so forth. If I can figure out how to grab the master object, I think I can program the rest and write the values.
hr = ADsGetObject( L"IIS://localhost/w3svc/1/root", IID_IADs, (void **)&pADs );
if ( FAILED( hr ) ) {
app_Level = 1;
goto error;
}I think what you are talking about here is a COM object, which is a little different to a C++ object. I don't know enough about it to explain further, however, so i will let someone else do that :). But as far as i know, the "object" is returned as the pADs pointer, you need to cast it from void*
[Window Detective] - Windows UI spy utility
-
I'm not a c++ programmer, but I need to be. I wrote a dll for installshield, that installs the web server program using shell as a custom action, but when I use their (IISHelper.dll) dll for programming the website, I run into problems. Thus I should write my own stuff in the same custom action. So I working with some sample code, that gets the object, but the sample code returns the HRESULT, and not the object, unless the object is IIS_IADs, like getting the value of a registry key?, in which it's there but you have to sort of dig it out. For now, I want to grab the default website in IIS5.1, and change the virtual path, the path to the code, and set the documents, mimes and so forth. If I can figure out how to grab the master object, I think I can program the rest and write the values.
hr = ADsGetObject( L"IIS://localhost/w3svc/1/root", IID_IADs, (void **)&pADs );
if ( FAILED( hr ) ) {
app_Level = 1;
goto error;
}without seeing more code, pADs is the variable that will be holding the com object you want to manipulate. pADs is likely a pointer to some COM interface (if you're not sure what that means you'll have to read up on the c/C++ langhuage and how to use pointers), thus the use of
&pADs
the "&" means you're taking a reference to something, so a pointer to a pointer. That's how all (or most) of the COM API functions work - they return an HRESULT to indicate the success or failure of a call, and if the function is supposed ot give you back an object, then it's done like this, with a pointer to a pointer of some interface.
¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Blow
-
without seeing more code, pADs is the variable that will be holding the com object you want to manipulate. pADs is likely a pointer to some COM interface (if you're not sure what that means you'll have to read up on the c/C++ langhuage and how to use pointers), thus the use of
&pADs
the "&" means you're taking a reference to something, so a pointer to a pointer. That's how all (or most) of the COM API functions work - they return an HRESULT to indicate the success or failure of a call, and if the function is supposed ot give you back an object, then it's done like this, with a pointer to a pointer of some interface.
¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Blow
ohoooo That was sort of like the registry function I wrote, In which it returns the Success code, and the object in the function contains the data. Much different than VB or C#, or JavaScript. Is it possible to export that com object, and pass it to another function for further processing?
HRESULT CA_WebInfo::get_IIS_VirtualDirectories( DWORD InstanceID ) {
HRESULT hr = CoInitialize( NULL ); if ( SUCCEEDED( hr ) ) { USES\_CONVERSION; CComPtr<IADs> pADs; CComPtr<IISApp2> pApp2; WCHAR ADSIPath\[50\]; //Get the IIsWebServer object - IIS://localhost/w3svc/xxx wsprintfW( ADSIPath, L"IIS://localhost/w3svc/%d", InstanceID ); hr = ADsGetObject( ADSIPath, IID\_IADs, (void \*\*)&pADs ); if ( SUCCEEDED( hr ) ) { //use the &pADS - Decode it, grab it or something }; pADs = NULL; //Get the IIsWebDirectory object - IIS://localhost/w3svc/xxx/root hr = ADsGetObject( ADSIPath, IID\_IADs, (void \*\*)&pADs ); if ( SUCCEEDED( hr ) ) { //Read the root folder of the IIsWebDirectory hr = pADs->QueryInterface( IID\_IISApp2, (void \*\*)&pApp2 ); if ( SUCCEEDED( hr ) ) { CComBSTR bstrVarname = L"Path"; CComVariant varAppRootPath; hr = pApp2->Get( bstrVarname, &varAppRootPath ); if ( SUCCEEDED( hr ) ) { //IISWebInfo->RootPath = OLE2T( varAppRootPath.bstrVal ); } }; //SUCCEEDED( hr ) - IID\_IISApp2 };//SUCCEEDED( hr ) - IID\_IADs };//SUCCEEDED( hr ) - CoInitialize( NULL ); CoUninitialize(); return hr;
}
-
ohoooo That was sort of like the registry function I wrote, In which it returns the Success code, and the object in the function contains the data. Much different than VB or C#, or JavaScript. Is it possible to export that com object, and pass it to another function for further processing?
HRESULT CA_WebInfo::get_IIS_VirtualDirectories( DWORD InstanceID ) {
HRESULT hr = CoInitialize( NULL ); if ( SUCCEEDED( hr ) ) { USES\_CONVERSION; CComPtr<IADs> pADs; CComPtr<IISApp2> pApp2; WCHAR ADSIPath\[50\]; //Get the IIsWebServer object - IIS://localhost/w3svc/xxx wsprintfW( ADSIPath, L"IIS://localhost/w3svc/%d", InstanceID ); hr = ADsGetObject( ADSIPath, IID\_IADs, (void \*\*)&pADs ); if ( SUCCEEDED( hr ) ) { //use the &pADS - Decode it, grab it or something }; pADs = NULL; //Get the IIsWebDirectory object - IIS://localhost/w3svc/xxx/root hr = ADsGetObject( ADSIPath, IID\_IADs, (void \*\*)&pADs ); if ( SUCCEEDED( hr ) ) { //Read the root folder of the IIsWebDirectory hr = pADs->QueryInterface( IID\_IISApp2, (void \*\*)&pApp2 ); if ( SUCCEEDED( hr ) ) { CComBSTR bstrVarname = L"Path"; CComVariant varAppRootPath; hr = pApp2->Get( bstrVarname, &varAppRootPath ); if ( SUCCEEDED( hr ) ) { //IISWebInfo->RootPath = OLE2T( varAppRootPath.bstrVal ); } }; //SUCCEEDED( hr ) - IID\_IISApp2 };//SUCCEEDED( hr ) - IID\_IADs };//SUCCEEDED( hr ) - CoInitialize( NULL ); CoUninitialize(); return hr;
}
Yes, it's just like any other parameter, though you do have to be careful to keep track of the ref count. Also, are you sure you want to be initializing/un-initializing COM in the one function? Wouldn't it make more sense to put that in your modules startup/shutdown code? If get_IIS_VirtualDirectories is part of some other COM object (implemented in C++) then CoInitialize should already have been called, making your call redundant. If the code has to execute in another thread, then you really want to put the CoInitialize call in the thread's initialization before it starts doing anything else (and you don't want to use CoInitialize, you'll want to look at CoInitializeEx and use the multi-threaded settings).
¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Blow
-
Yes, it's just like any other parameter, though you do have to be careful to keep track of the ref count. Also, are you sure you want to be initializing/un-initializing COM in the one function? Wouldn't it make more sense to put that in your modules startup/shutdown code? If get_IIS_VirtualDirectories is part of some other COM object (implemented in C++) then CoInitialize should already have been called, making your call redundant. If the code has to execute in another thread, then you really want to put the CoInitialize call in the thread's initialization before it starts doing anything else (and you don't want to use CoInitialize, you'll want to look at CoInitializeEx and use the multi-threaded settings).
¡El diablo está en mis pantalones! ¡Mire, mire! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! Personal 3D projects Just Say No to Web 2 Point Blow
I was using the code sample to try and sort of reverse engineer some sample code, and get a clear understanding of it first. The Big Picture is that I'm trying to write my own Custom Action DLL for InstallShield Pro, that installs the web server, looks at the metadata, if it's XPPro/Vista/7 with 1 default website, then change the virtual path, program the mimes, documents so my asp.net product will work. I didn't know what the scope of coinitialize was, or what it does, and I prefer to just write 1 giant function first. I wrote this first, as the main function, in which I want to fork out to another function based on the IIS Version installed. But I'm stuck creating my first engine function, that does the work. in switch case 5, I want to run the IIS job.
void CA_WebInfo::create_WebServer( CString msi_DIR_AppVolumeFolder_II ) {
bool iis\_Result = false; int program\_ExitCode = 0; unsigned long iis\_MajorVersion; unsigned long iis\_MinorVersion; CA\_Registry caReg; //Is the Web Server Installed iis\_Result = IIS\_Installed(); if ( iis\_Result == false ) { program\_ExitCode = install\_WebServer( msi\_DIR\_AppVolumeFolder\_II ); } iis\_Result = IIS\_Installed(); if ( iis\_Result == true ) { iis\_MajorVersion = caReg.get\_IIS\_MajorVersion(); iis\_MinorVersion = caReg.get\_IIS\_MinorVersion(); //Add the Website depending on the version of IIS int result\_ADSI = 0; switch ( iis\_MajorVersion ) { case 5: attach\_IIS5\_XP(); result\_ADSI = get\_IIS\_VirtualDirectories( 1 ); break; case 6: break; case 7: break; } }
}
I know I have to attach to the metadata first, see what it is, and then take action. I have written this in VB with great success, but c++ is lights years away. This is my intialization of the IIS MetaData. I hope my explanation makes sense, this is my first c++ project since 28 years ago.
HRESULT CA_WebInfo::attach_IIS5_XP(void) {
HRESULT hr; IADs \*pADs = NULL; IISApp2 \*pApp2 = NULL; IISApp3 \*pApp3 = NULL; DWORD instanceID = 1; int app\_Level = 0; hr = CoInitializeEx( NULL, COINIT\_MULTITHREADED ); if ( FAILED( hr ) ) { goto error; } hr = ADsGetObject( L"IIS://localhost/w3svc/1/root", IID\_IADs, (void \*\*)&pADs ); if ( FAILED( hr ) ) { app\_Level = 1; goto error; } hr = pADs->QueryInterface(