M
mabra
Hi All !
Sorry for my crossposting, I am not completely sure about which group is
really of any help. I started using the WUA [windows update agent] COM
API from C#. I created an interop assembly and my code compiles fine and
the most parts are running as expected.
I first create a UpdateSession object and look for updates, which are
downloaded. Then I create an UpdateInstaller, but this fails:
UpdateInstaller installer = (UpdateInstaller)
this.session.CreateUpdateInstaller(); //CRASH
I might have a wrong variable type here really. If I use VS's object
browser, I feel, I do not understand, why there are so many different
interfaces, like IUpdateInstaller, IUpdateInstaller2 etc.
I tried also:
IUpdateInstaller2 installer = (IUpdateInstaller2)
this.session.CreateUpdateInstaller(); //CRASH
May be, someone can help?
Thanks so far and
best regards,
Manfred
I append a repro here [hopefully, this is readable]
/*
Name: DemoComError.cs
Compile: csc /nologo /debug:full /t:exe /out
emoComError.exe
/r:Interop.WUAApiLib.dll /r:log4net.dll DemoComError.cs
TLBIMP: TLBIMP /out:Interop.WUAApiLib.dll /namespace:Interop.WUALib
C:\WINDOWS\system32\wuapi.dll
TlbImp warning: At least one of the arguments for
'UpdateInstaller.get_ParentHwnd' can not be marshaled by the runtime
marshaler. Such arguments will therefore be passed as a pointer and
may require unsafe code to manipulate.
Error:
Unhandled Exception: System.Runtime.InteropServices.COMException
(0x80020008): Bad variable type.
at Interop.WUALib.IUpdateSession2.CreateUpdateInstaller()
at AdminTools.WindowsUpdateInfo.InstallUpdates() in
d:\Develop\Dev\Experimente\WSUS\Net\WUAWrapper\DemoComError.cs:line 87
*/
using System;
using System.Runtime.InteropServices;
using Interop.WUALib;
namespace AdminTools
{
public class WUAApp
{
public static void Main(string[] args)
{
if(args.Length != 0)
{
WindowsUpdateInfo wui = new WindowsUpdateInfo(args[0]);
int count = wui.DetectUpdates(); //condition...
if(count != 0) wui.InstallUpdates();
}
else
{
Console.WriteLine("Args!!! [p1=computer]");
}
}
}//class
public class WindowsUpdateInfo
{
private string computerName;
private UpdateSession session;
private UpdateCollection updates;
public WindowsUpdateInfo(string computerName)
{
this.computerName = computerName;
try
{
Type type = Type.GetTypeFromProgID("Microsoft.Update.Session",
computerName, true);
this.session = (UpdateSession) Activator.CreateInstance(type);
}
catch(COMException ce)
{
Console.WriteLine("COMException;Exception:{0},Code:{1}", ce.Message,
ce.ErrorCode);
}
}
public int DetectUpdates()
{
IUpdate u;
IUpdateSearcher us = session.CreateUpdateSearcher();
ISearchResult sr = us.Search("IsInstalled=0 and Type='Software'");
this.updates = sr.Updates;
for(int i = 0; i < this.updates.Count; i++)
{
u = this.updates; //do something with update;show.
}
Console.WriteLine("Updates:{0}", this.updates.Count);
return this.updates.Count;
}
public void InstallUpdates()
{
UpdateCollection updates = new UpdateCollection();
for(int i = 0; i < this.updates.Count; i++)
{
updates.Add(this.updates);
}
Console.WriteLine("Added {0} updates to install.", updates.Count);
UpdateInstaller installer = (UpdateInstaller)
this.session.CreateUpdateInstaller(); //(87)CRASH
installer.Updates = updates;
IInstallationResult installationResult = installer.Install();
for(int i = 0; i < updates.Count; i++)
{
Console.WriteLine("Installed:{0},Result:{1}.", updates.Title,
installationResult.GetUpdateResult(i).ResultCode);
}
}
}//class
}//namespace
Sorry for my crossposting, I am not completely sure about which group is
really of any help. I started using the WUA [windows update agent] COM
API from C#. I created an interop assembly and my code compiles fine and
the most parts are running as expected.
I first create a UpdateSession object and look for updates, which are
downloaded. Then I create an UpdateInstaller, but this fails:
UpdateInstaller installer = (UpdateInstaller)
this.session.CreateUpdateInstaller(); //CRASH
I might have a wrong variable type here really. If I use VS's object
browser, I feel, I do not understand, why there are so many different
interfaces, like IUpdateInstaller, IUpdateInstaller2 etc.
I tried also:
IUpdateInstaller2 installer = (IUpdateInstaller2)
this.session.CreateUpdateInstaller(); //CRASH
May be, someone can help?
Thanks so far and
best regards,
Manfred
I append a repro here [hopefully, this is readable]
/*
Name: DemoComError.cs
Compile: csc /nologo /debug:full /t:exe /out

/r:Interop.WUAApiLib.dll /r:log4net.dll DemoComError.cs
TLBIMP: TLBIMP /out:Interop.WUAApiLib.dll /namespace:Interop.WUALib
C:\WINDOWS\system32\wuapi.dll
TlbImp warning: At least one of the arguments for
'UpdateInstaller.get_ParentHwnd' can not be marshaled by the runtime
marshaler. Such arguments will therefore be passed as a pointer and
may require unsafe code to manipulate.
Error:
Unhandled Exception: System.Runtime.InteropServices.COMException
(0x80020008): Bad variable type.
at Interop.WUALib.IUpdateSession2.CreateUpdateInstaller()
at AdminTools.WindowsUpdateInfo.InstallUpdates() in
d:\Develop\Dev\Experimente\WSUS\Net\WUAWrapper\DemoComError.cs:line 87
*/
using System;
using System.Runtime.InteropServices;
using Interop.WUALib;
namespace AdminTools
{
public class WUAApp
{
public static void Main(string[] args)
{
if(args.Length != 0)
{
WindowsUpdateInfo wui = new WindowsUpdateInfo(args[0]);
int count = wui.DetectUpdates(); //condition...
if(count != 0) wui.InstallUpdates();
}
else
{
Console.WriteLine("Args!!! [p1=computer]");
}
}
}//class
public class WindowsUpdateInfo
{
private string computerName;
private UpdateSession session;
private UpdateCollection updates;
public WindowsUpdateInfo(string computerName)
{
this.computerName = computerName;
try
{
Type type = Type.GetTypeFromProgID("Microsoft.Update.Session",
computerName, true);
this.session = (UpdateSession) Activator.CreateInstance(type);
}
catch(COMException ce)
{
Console.WriteLine("COMException;Exception:{0},Code:{1}", ce.Message,
ce.ErrorCode);
}
}
public int DetectUpdates()
{
IUpdate u;
IUpdateSearcher us = session.CreateUpdateSearcher();
ISearchResult sr = us.Search("IsInstalled=0 and Type='Software'");
this.updates = sr.Updates;
for(int i = 0; i < this.updates.Count; i++)
{
u = this.updates; //do something with update;show.
}
Console.WriteLine("Updates:{0}", this.updates.Count);
return this.updates.Count;
}
public void InstallUpdates()
{
UpdateCollection updates = new UpdateCollection();
for(int i = 0; i < this.updates.Count; i++)
{
updates.Add(this.updates);
}
Console.WriteLine("Added {0} updates to install.", updates.Count);
UpdateInstaller installer = (UpdateInstaller)
this.session.CreateUpdateInstaller(); //(87)CRASH
installer.Updates = updates;
IInstallationResult installationResult = installer.Install();
for(int i = 0; i < updates.Count; i++)
{
Console.WriteLine("Installed:{0},Result:{1}.", updates.Title,
installationResult.GetUpdateResult(i).ResultCode);
}
}
}//class
}//namespace