InsertMenuItem cutting off the string to first char - c#

I am trying to modify window's system menu using InsertMenuItem (instead of InsertMenu - the reason is that I want to insert submenus eventually). Language is C#.
Tried inserting a new item, tried getting existing item and reinserting it, it inserts, but the item string is shown in the menu only as the first character. Anyone have a clue about what I am missing?
// try creating one from scratch
MENUITEMINFO it = new MENUITEMINFO();
it.cbSize = (uint)Marshal.SizeOf(it);
it.fMask = 64;// MIIM_STRING
it.wID = 12345;
it.dwTypeData = "Now is the time";
it.fType = 0;
it.cch = 0;
InsertMenuItem(hSysMenu, 7, true, ref it);
//try copying one
GetMenuItemInfo(hSysMenu, (uint)0, true, ref it);
it.cch += 10;
it.dwTypeData = new string(' ', (int)(menuItemInfo.cch+10));
GetMenuItemInfo(hSysMenu, (uint)0, true, ref it);
it.wID = 123456;
var err = InsertMenuItem(hSysMenu, 1, true, ref it);
The result of the above code

Ok I finally figured it out. I will leave this here so maybe someone else later will find it when they are baffled by this.
The reason was that the InsertMenuItem p/invoke was defined with
[DllImport("user32.dll")] in the pinvoke.net site - see https://www.pinvoke.net/default.aspx/user32/insertmenu.html?diff=y
and it needs to be
[DllImport("user32.dll", CharSet = CharSet.Auto) ]
I changed the pinvoke.net page to reflect it.

Related

C# - Getting the full picture from WUAPI

I am trying to collect an accurate picture of Windows Updates, specifically KB installations, on a number of different machines. I've tried a number of different pieces of code that I've found scattered about, but I still cannot seem to create an accurate picture of what is installed. By accurate, I mean that whatever I gather seems to be a subset of what is shown when I check the Windows Update History on the machine using the Windows UI! Can't seem to figure this out!
Here are a few things I've tried;
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
ISearchResult sResult = uSearcher.Search("IsInstalled=1");
foreach (IUpdate update in sResult.Updates)
{
foreach (string kbaid in update.KBArticleIDs)
{
txtAllUpdates.AppendText(kbaid + Environment.NewLine);
}
}
I also tried adding code within this same routine to gather all of the updates within the Bundled Updates field, like so;
foreach (IUpdate update2 in update.BundledUpdates)
{
txtAllUpdates.AppendText("\t--> " + update2.Title + Environment.NewLine);
foreach (string kbaid2 in update2.BundledUpdates)
{
string kbNo = GetKBNo(update2.Title.ToLower());
txtAllUpdates.AppendText("\t\t" + kbNo);
}
}
I also tried looking at the Update History, but that provided me with yet another set of data - still not complete!
UpdateSession updateSession = new UpdateSession();
IUpdateSearcher updateSearcher = updateSession.CreateUpdateSearcher();
int count = updateSearcher.GetTotalHistoryCount();
MessageBox.Show("Total Count = " + count);
IUpdateHistoryEntryCollection history = updateSearcher.QueryHistory(0, count);
for (int i = 0; i < count; ++i)
{
txtAllUpdates.AppendText("\t\t\t" + history[i].Title);
}
I also checked into some code that leverages the registry, but from what I've read, that's not the right way to do things. At this point, I'm performing a number of different queries, searching entries for "KB" references and building a list and removing duplicates, but I'm still not getting the same list I see on the screen! Even if this did work, it can't possibly be the right way to go - I feel like I must be missing something.
Finally, I tried to just get information on when updates were last checked for and installed - even that doesn't match up with what is displayed. I did this with the following code;
var auc = new AutomaticUpdatesClass();
DateTime? lastInstallationSuccessDateUtc = null;
if (auc.Results.LastInstallationSuccessDate is DateTime)
lastInstallationSuccessDateUtc = new DateTime(((DateTime)auc.Results.LastInstallationSuccessDate).Ticks, DateTimeKind.Utc);
DateTime? lastSearchSuccessDateUtc = null;
if (auc.Results.LastSearchSuccessDate is DateTime)
lastSearchSuccessDateUtc = new DateTime(((DateTime)auc.Results.LastSearchSuccessDate).Ticks, DateTimeKind.Utc);
lblInstall.Text += lastInstallationSuccessDateUtc.ToString();
lblSearch.Text += lastSearchSuccessDateUtc.ToString();
Does anyone have some expertise in this area? Really want to get this done right!
Thanks for taking the time to read!
Respectfully,
Marshall
All the various ways to find installed software is incomplete, so I used a variety of ways in Get-KbInstalledUpdate, which I describe as a:
Replacement for Get-Hotfix, Get-Package, searching the registry and searching CIM for updates
Though I haven't tried this way, which is essentially:
$session = New-Object -ComObject "Microsoft.Update.Session"
$updatesearcher = $session.CreateUpdateSearcher()
$count = $updatesearcher.GetTotalHistoryCount()
$updates = $updatesearcher.QueryHistory(0, $count)

C# - When I use task::wait() method it throwing the exception

I programming Windows Store App, and I have following problem.
I use this code to record the array of numbers to a file:
auto item = KnownFolders::PicturesLibrary;
task<StorageFile^> getFileTask(item->CreateFileAsync(filename, CreationCollisionOption::ReplaceExisting));
getFileTask.then([=](StorageFile^ storageFile)
{
return storageFile->OpenAsync(FileAccessMode::ReadWrite);
}).then([](IRandomAccessStream^ m_istream)mutable
{
unsigned char a[] = { 1, 2, 3 };
auto arr = ref new Array<unsigned char>(a, sizeof(a));
auto outs = m_istream->GetOutputStreamAt(0);
auto dw = ref new DataWriter(outs);
dw->WriteBytes(arr);
return dw->StoreAsync();
}).wait();
Code is successfully compiled, but it provide an error:
MyTest.exe has triggered a breakpoint.
And it point to _REPORT_PPLTASK_UNOBSERVED_EXCEPTION(); line, that be found in ppltasks.h.
If I use .then([](DataWriterStoreOperation^){}) instead .wait(), My application don't compile with this error:
error C2338: incorrect parameter type for the callable object in 'then';
consider _ExpectedParameterType or task<_ExpectedParameterType> (see below).
Why is that? I using VS2013. Please help me.
I found the solution of this problem!!!
Right code:
unsigned char a[] = { 1, 2, 3 };
auto arr = ref new Array<unsigned char>(a, sizeof(a));
auto m_istream = ref new InMemoryRandomAccessStream();
auto outs = m_istream->GetOutputStreamAt(0);
auto dw = ref new DataWriter(outs);
dw->WriteBytes(arr);
task<unsigned int>(dw->StoreAsync()).then([=](unsigned int)
{
return item->CreateFileAsync(filename, CreationCollisionOption::ReplaceExisting);
}).then([=](StorageFile^ storageFile)
{
return storageFile->OpenAsync(FileAccessMode::ReadWrite);
}).then([=](IRandomAccessStream^ new_stream)
{
return RandomAccessStream::CopyAsync(m_istream->GetInputStreamAt(0), new_stream->GetOutputStreamAt(0));
}).then([=](UINT64 copiedBytes)
{
return;
});

Using Hidden Security Icons in Taskdialog

I am trying to display a Security Success Icon (with the blue background) in TaskDialog message box. This is not one of the enum values of TaskDialogStandardIcon. Reference: http://dotnet.dzone.com/articles/using-new-taskdialog-winapi.
How do I assign these non standard values to ((TaskDialog)sender).Icon ? Is it even possible in C#? C#
Any pointers would be really helpful.
Regards,
Ashwin
I think you will need to import TaskDialog function from comctl32.dll yourself:
static class TaskDialogWrapper
{
[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
static extern int TaskDialog(IntPtr hWnd, IntPtr hInstance, string pszWindowTitle, string pszMainInstruction, string pszContent, TaskDialogCommonButton dwCommonButtons, IntPtr pszIcon, out IntPtr pnButton);
public static TaskDialogCommonButton Show(IntPtr handle, IntPtr instance, string title, string instructionText, string content, TaskDialogCommonButton commonButtons, TaskDialogCommonIcon commonIcon)
{
IntPtr resultButton;
if (TaskDialog(handle, instance, title, instructionText, content, commonButtons, new IntPtr((int)commonIcon), out resultButton) != 0)
throw new InvalidOperationException();
return (TaskDialogCommonButton)resultButton;
}
}
[Flags()]
enum TaskDialogCommonButton
{
Ok = 0x1,
Yes = 0x2,
No = 0x4,
Cancel = 0x8,
Retry = 0x10,
Close = 0x20
}
enum TaskDialogCommonIcon
{
ShieldGrey = 65527,
ShieldOk = 65528,
ShieldError = 65529,
ShieldWarning = 65530,
ShieldBlue = 65531,
Shield = 65532,
Information = 65533,
Error = 65534,
Warning = 65535,
}
To use your own icon from a file, you will need to import TaskDialogIndirect.
(Btw., I found many other interesting icon styles for TaskDialogCommonIcon. You could add e.g.:
enum TaskDialogCommonIcon
{
None = 0,
Sheet = 2,
ExplorerFolderOpen = 3,
ExplorerFolderFlat = 5,
ExplorerFolderLeft = 6,
Search = 8,
ExplorerFolderClosed = 10,
ExplorerGames = 14,
Application = 15,
TransparentSpace = 17,
ExplorerSearch = 18,
TextFile = 19,
Letter = 20,
Picture = 21,
Diashow = 103,
// ...
}
I know that this is an old question, but I was looking for something similar, so I thought I'd pass along what I've found. Using the information posted by #KnorxThieus, I found a way to use the "hidden" security icons in the TaskDialog without going through the DLLImport process outlined above. Using the actual values he provided for the TaskDialogCommonIcon enumeration, I found that you can simply cast them to the appropriate type (i.e., the TaskDialogCommonIcon), and your application should display them properly.
Please note, I'm using the WindowsAPICodePack version 1.1.2 from Nuget (nuget.org/packages/WindowsAPICodePack-Core), and the code below has been converted from Visual Basic using the Telerik Code Converter (http://converter.telerik.com/), so it's possible that you may have to do some fine-tuning in C#:
if (TaskDialog.IsPlatformSupported) {
using (TaskDialog dialog = new TaskDialog()) {
dialog.Caption = "TESTING";
dialog.InstructionText = "THIS IS A TEST";
dialog.Text = "This is a test of casting a value to the desired Icon type for a TaskDialog.";
// Produces the green shield with green background
dialog.Icon = (TaskDialogStandardIcon)65528;
dialog.OwnerWindowHandle = this.Handle;
dialog.Show();
}
}
In my testing, this seems to work for all of the enumerations #KnorxThieus listed, as well as several others. I'm trying to figure out if there's a similar method for setting the Icon property to another (non-standard) image file, but I've been unsuccessful with that so far. I hope this helps anyone that stumbles across this in the future.
Take a look at the Ookii.Dialogs. It implements the TaskDialog and others dialogs as well, and have versions targeting WPF and Windows Forms.

problems with C# Port of Recast Detour Navigation Mesh for XNA, A* Pathing

Update 10/03
Ok, so i figured out the problem. C# is a funny old language..I changed
int navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, false);
to
var navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, false);
and finally im getting the pathfinding values to work!
When i debug the routeNavMesh array fills up with the values i require.
http://i.imgur.com/QgH8UL6.png [Screencap of debug in question]
Ill update again once im done.
Having some major problems getting a navigational mesh to work, in particular i cant get it to do any pathfinding or get it to respond to my vector3 input in any useful way.
Im working on the sunburn engine, it sits on top of XNA 4.0, so all of XNAs functions are still usable.
Recently Recast Navigation from digesting Duck's blog was ported over to c# and i've used it to create navigation meshes for my levels. Here is a link to the tutorial/guide i've been trying to follow: http://xboxforums.create.msdn.com/forums/p/109484/647991.aspx
im not sure how to pass in the start and end values on the getpath segment, are these meant to be values in world space or object space or something? If i do vector3 values and enter them as the start and end values( and then subsequently set them in a place on the array), i dont get an array of values that shows path finding, i just get those two verbatim values inside the navmeshroute array.
Here is where i try and run the path, its in my Update.
routePolys = new ushort[dtStatNavMesh.MAX_POLYS];
navMeshRoute = new Vector3[dtStatNavMesh.MAX_POLYS];
if (ks.IsKeyDown(Keys.L))
{
if (!runOnce)
{
start = new Vector3(0, 0, 0);
end = new Vector3(1000, 0, 1000);
ppos = x;
navMeshRoute[0].X = start.X;
navMeshRoute[0].Y = start.Y;
navMeshRoute[0].Z = start.Z;
navMeshRoute[count].X = end.X;
navMeshRoute[count].Y = end.Y;
navMeshRoute[count].Z = end.Z;
int navMeshStart = 0;
navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, true);
Console.WriteLine("navMeshPC" + navMesh.getPolyCount());
int navMeshCount = navMesh.GetPath(ref start, ref end, routePolys, navMeshRoute, true);
while (navMeshStart < navMeshCount)
{
routeNode = navMeshRoute[navMeshStart++];
}
Console.Out.WriteLine("NMc : " + navMeshCount);
}
}

Can anyone explain the major features of a VDPROJ file?

I'm sure there must be some documentation on MSDN somewhere, but I couldn't find it. It looks like some subset/variation of JSON. Really, this question grew out of something that has always bugged me: what do all the 8:s and 3:s mean? Is this some a version number of some kind? Maybe a typing scheme? Every VDPROJ excerpt I've ever seen is filled with these "eight-colon" and "three-colon" prefixes, but this is not the sort of question search engines are really good for.
"DeployProject"
{
"VSVersion" = "3:800"
"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
"IsWebType" = "8:FALSE"
"ProjectName" = "8:ProjectNameRedacted"
"LanguageId" = "3:1033"
"CodePage" = "3:1252"
"UILanguageId" = "3:1033"
"SccProjectName" = "8:"
"SccLocalPath" = "8:"
"SccAuxPath" = "8:"
"SccProvider" = "8:"
"Hierarchy"
{
"Entry"
{
"MsmKey" = "8:_02F97BB7BD104F1AAA1C97C854D5DC99"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
...
If anyone just wants to berate my pitiful Google-fu, that's fine too.
As #R. Matveev pointed out, the prefix numbers likely indicate the type of data stored in the property. This would be useful when deserializing the file into an object structure.
I doubt the source code which Visual Studio used to read/write the files was ever made open source, so it's no wonder that web searches returned nothing.
The best I could find was this page on OLE Automation data types, which may not have been the actual constants, but the data types seem to match the values in the *.vdproj file.
2.2.7 VARIANT Type Constants
typedef enum tagVARENUM
{
VT_EMPTY = 0x0000,
VT_NULL = 0x0001,
VT_I2 = 0x0002,
VT_I4 = 0x0003, // 4-byte signed integer
VT_R4 = 0x0004,
VT_R8 = 0x0005,
VT_CY = 0x0006,
VT_DATE = 0x0007,
VT_BSTR = 0x0008, // BSTR (string data)
VT_DISPATCH = 0x0009,
VT_ERROR = 0x000A,
VT_BOOL = 0x000B, // Boolean value
VT_VARIANT = 0x000C,
VT_UNKNOWN = 0x000D
...
} VARENUM;

Categories