|
Hi all,
I was looking for a way to Ngen my program on the target system at setup. I found an example on MSDN[^] in Visual Basic. Although I don't know anything about VB, translation usually isn't too hard, but this time I'm finding it difficult.
If anyone could lend me a hand at this that would be great. This is the code concerned:
Private Declare Function GetCORSystemDirectory Lib "mscoree.dll" _
(<runtime.interopservices.marshalas( _<br="" mode="hold" /> System.Runtime.InteropServices.UnmanagedType.LPWStr)> _
ByVal Buffer As System.Text.StringBuilder, _
ByVal BufferLength As Integer, ByRef Length As Integer) As Integer
<security.permissions.securitypermission(security.permissions.securityaction.demand)> _
Public Overrides Sub Install(ByVal savedState As _
System.Collections.IDictionary)
MyBase.Install(savedState)
Dim Args As String = Me.Context.Parameters.Item("Args")
If Args = "" Then
Throw New InstallException("No arguments specified")
End If
' Gets the path to the Framework directory.
Dim Path As New System.Text.StringBuilder(1024)
Dim Size As Integer
GetCORSystemDirectory(Path, Path.Capacity, Size)
Dim P As Process
' Quotes the arguments, in case they have a space in them.
Dim Si As New ProcessStartInfo(Path.ToString() & "ngen.exe", Chr(34) _
& Args & Chr(34))
Si.WindowStyle = ProcessWindowStyle.Hidden
Try
P = Process.Start(Si)
P.WaitForExit()
Catch e As Exception
Throw New InstallException(e.Message)
End Try
End Sub
</security.permissions.securitypermission(security.permissions.securityaction.demand)>
Might be best to check out the code from the MSDN example though, since it provides the proper context. Thanks in advance!
Standards are great! Everybody should have one!
|
|
|
|
|
|
Thanks, didn't know this site. This actually gives me all but the part I don't understand, which is:
Private Declare Function GetCORSystemDirectory Lib "mscoree.dll" _
(<runtime.interopservices.marshalas( _<br="" mode="hold" /> System.Runtime.InteropServices.UnmanagedType.LPWStr)> _
ByVal Buffer As System.Text.StringBuilder, _
ByVal BufferLength As Integer, ByRef Length As Integer) As Integer
Looks like some kind of P/Invoke signature import or something . The converter you gave me gets me a "stack empty" error.
Standards are great! Everybody should have one!
|
|
|
|
|
Yes, it looks like a P/Invoke signature. Did you try converting it to c# yourself?
|
|
|
|
|
|
In the original there is System.Text.StringBuilder, why did you change it with just String? If you've never worked with P/Invoke, I suggest you have a look at this: P/Invoke[^]
|
|
|
|
|
You're absolutely right. Should have noticed that. Take a look at my second try (below) please.
Standards are great! Everybody should have one!
|
|
|
|
|
Ok, I actually got it to compile using:
[DllImport("mscoree.dll")]<br />
static extern int GetCORSystemDirectory(<br />
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] StringBuilder buffer,<br />
Int32 buffer_length,<br />
out Int32 length<br />
);
And then calling the function like this:
<br />
System.Text.StringBuilder Path = new System.Text.StringBuilder(1024);<br />
int Size;<br />
GetCORSystemDirectory(Path, Path.Capacity, out Size);<br />
Still doesn't seem to be working though, can you tell me if the signature is right?
Standards are great! Everybody should have one!
|
|
|
|
|
You should also have notices that original code uses System.Runtime.InteropServices.UnmanagedType.LPWStr and not System.Runtime.InteropServices.UnmanagedType.LPStr
Also, third parameter of GetCORSystemDirectory Function is DWORD* so you should pass a reference to int.
|
|
|
|
|
Ok, thanks for the advice I've updated the code to:
[DllImport("mscoree.dll")]
static extern int GetCORSystemDirectory(
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] StringBuilder buffer,
Int32 buffer_length,
ref Int32 length
);
And the call is now like this:
System.Text.StringBuilder Path = new System.Text.StringBuilder(1024);
int Size = 0;
GetCORSystemDirectory(Path, Path.Capacity, ref Size);
Still it's not working If I could only set a breakpoint to find out why, but this doesn't seem to be supported for installer projects...
Standards are great! Everybody should have one!
|
|
|
|
|
Are you getting an error/exception or is it returning wrong data? Did you turn the stringbuilder into string?
|
|
|
|
|
I'm on Vista and getting code 2869, no further explanation. I've googled it for a bit and now suspect it's a security problem. This would mean the p/invoke call is actually good now. This is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
namespace InstallationHelper
{
[RunInstaller(true)]
public partial class InstallationHelper : Installer
{
[DllImport("mscoree.dll")]
static extern int GetCORSystemDirectory(
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] StringBuilder buffer,
Int32 buffer_length,
ref Int32 length
);
public InstallationHelper()
{
InitializeComponent();
}
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Install(System.Collections.IDictionary savedState)
{
base.Install(savedState);
string Args = this.Context.Parameters["Args"];
if (Args == "")
{
throw new InstallException("No arguments specified");
}
System.Text.StringBuilder Path = new System.Text.StringBuilder(1024);
int Size = 0;
GetCORSystemDirectory(Path, Path.Capacity, ref Size);
Process P;
ProcessStartInfo Si = new ProcessStartInfo(Path.ToString() + "ngen.exe", "\"" + Args + "\"");
Si.WindowStyle = ProcessWindowStyle.Maximized;
try
{
P = Process.Start(Si);
P.WaitForExit();
}
catch (Exception e)
{
throw new InstallException(e.Message);
}
}
}
}
Standards are great! Everybody should have one!
|
|
|
|
|
Yes, according to google it looks like a problem with permissions and vista. You could try running it on XP or calling unmanaged function from a normal windows application so that you can set breakpoint.
|
|
|
|
|
Ok, problem solved! Cleaning up seems to be the right thing to do here: Just removing the constructor was enough to get the thing going for some reason . Thanks a bunch Giorgi, you've been a real help!
Standards are great! Everybody should have one!
|
|
|
|
|
Glad to help you
|
|
|
|
|
I have a dataset with nested tables:
<a>
<b>
<c>
<first>1</first>
<second>2</second>
</c>
</b>
</a>
and I´m trying to write this dataset into a xml file, but I don´t want to write the first element of the dataset. I´m using the dataset1.WriteXml() method. I want the xml file to look like this:
<b>
<c>
<first>1</first>
<second>2<second>
</second></second></c>
</b>
How can I accomplish this? Can anyone help me please?
cellardoor
|
|
|
|
|
Hi all,
I have the following piece of code that adds a new tab to a tabpage control.
...
RichTextBox rtext = new RichTextBox();
rtext.Dock = DockStyle.Fill;
tabControlMain.TabPages[tabControlMain.TabPages.Count-1].Controls.Add(rtext);
...
Now I am trying to load some different file(s) into the newely created richtextboxes found on each of the newely created tabs. And this is were I get stuck. How can I access the RichTextBox created on the new tab and be able to load a file into it??
Can anyone please help??
Many Thanks
Regards,
The only programmers that are better that C programmers are those who code in 1's and 0's
Programm3r
My Blog: ^_^
|
|
|
|
|
If there is only richtextbox on the tab and no other controls, you can access it like this: tabControlMain.TabPages[tabControlMain.TabPages.Count-1].Controls[0] Another way is to assign name to the richtextbox before you add it to the tab and access it through its name: tabControlMain.TabPages[tabControlMain.TabPages.Count-1].Controls["richtextboxname"]
Don't forget to cast it to richtextbox.
|
|
|
|
|
|
There is no need to have a separate array of richtextboxes that hold the reference.
|
|
|
|
|
I.E. if oen would do it like this, there would be no need .... right ?
RichTextBox text = (RichTextBox)tabControlMain.TabPages[tabControlMain.TabPages.Count - 1].Controls[0];
The only programmers that are better that C programmers are those who code in 1's and 0's
Programm3r
My Blog: ^_^
|
|
|
|
|
Right!
|
|
|
|
|
|
You are welcome
|
|
|
|
|
hi all
i want to show a column value from datatable.I tried as below . it doesnt shows the values.
pls help.
SqlDataAdapter adpt = new SqlDataAdapter(cmd);<br />
DataTable dtCust1 = new DataTable("CustomerDatTab");<br />
adpt.Fill(dtCust1);<br />
<br />
dataGridView1.DataSource=dtCust1;
<br />
<br />
DataRow dr = new DataRow();<br />
foreach (DataRow dr in dtCust1.Rows)<br />
comboBox1.Items.Add(dr.ToString());<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
thank u
senthil
|
|
|
|