|
I have created a service in c#.
And I am executing a Process.Start command in this code ( OF SERVICE PROJECT) .
that command(Process.Start ) is executing sucessfully for local drives but it throws Win32Exception (means There was an error in opening the associated file) at network path. for example path is \\computername\folder1\folder2\some.exe
AND it heapens only with Service type application all other applications are executing any process at network path (i.e \\computername\folder1\folder2\some.exe)successfully with this command(Process.Start).
Can any body tell how will I make my Service to execute any Process at network path?
r00d0034@yahoo.com
|
|
|
|
|
As default a service runs as the "System" user. This user dont have permissions to access shares on other computers.
You have to change toe user that the service logs on as. Change that to a user that have permissions to access the share, then it works
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
I still can't find out how to convert this managed string into a unmanaged char[20].
Specifically: I have a char called FILENAME
char filename __nogc[20] ;
and a managed string called STR.
String* str ;
Does anyone have any idea how to read STR into FILENAME?
Please don't tell me it can't be done...
Thanks,
KBL
|
|
|
|
|
|
is for Managed Visual C++.NET..
Suppose I have two Strings.
String1 = C://files
String2 = data.txt
I want to concatenate the two strings while inserting a character between them, to get a new string:
C://file/data.txt
Here the character is an extra "/".
Once this is done, I would like to convert the new string to a char[20].
Does anyone know how to perform this task?
I would be very grateful..
Thanks
KBL
|
|
|
|
|
There are no overloaded + or += operators for Strings in MC++, so one must use the plain member functions:
String *String1 = S"C:\\files";<br />
String *String2 = S"data.txt";<br />
<br />
String1 = String::Concat(String1, S"\\", String2);<br />
<br />
<br />
char achCStr[20];<br />
<br />
wchar_t *pGuts = PtrToStringArray(String1);<br />
int iChrs = ::WideCharToMultiByte(CP_ACP, 0, pGuts, String1->Length, achCStr, 20, NULL, NULL);<br />
achCStr[iChrs] = '\0';
PtrToStringArray() was posted earlier at http://www.codeproject.com/script/comments/forums.asp?forumid=3785&select=364715#xx364715xx[^] , and explained 2 posts earlier in that thread.
String::Concat() returns a concatenated copy of between 2 and 4 strings, and since the lengths of all the Strings are calculated prior to assembling them into the returned String, should avoid multiple temporary copies usually associated with concatenation (nice!). Insert() works like strcat() when the start position is the same as the original String's length, but as you can see it requires an extra temporary String copy
It's undocumented, but when I do something like the above, I pass 'String1->Length+1' in WideCharToMultiByte(), which avoids having to add the terminating null character afterwards. Like CString and std::string, CLR Strings seem to always have a terminating null appended to them, and I have never seen a case where they haven't.
Cheers
|
|
|
|
|
Hi -
I have a question which is probably very simple...
I'm trying to build an application which requires an open-file dialog like the explorer in windows (or like any other app that works with files). I want to use Windows Forms in Visual C++.net.
Does anyone have some canned code that generates an open-file dialog with a TreeView to the left and a ListView to the right, that allows the user to select a file from the ListView by clicking on the appropriate icon?
I would be very, very grateful!
Thanks,
KBL
KBL
|
|
|
|
|
|
Visual Studio 6
** loads a string of "len" byte in message at the given index
** message has to be able to contain "len" + idx bytes
*/
void CMessageProtocol::LoadValueInMessage( char *message , int idx, string &command, int len )
{//private:
int i;
// this loop load the command in message
for ( i = 0; command[i] && (i < len) ; i++ )
{
message[idx] = command[i];
idx++;
}
// this loop is used for padding
for ( ; i < len; i++)
{
message[idx] = PROT_PADDING;
idx++;
}
}
Visual Studio .NET
void GEMBrokerMessengerProtocol::CGEMMessageProtocol::LoadValueInMessage(SByte* Message,
Int32 idx,
System::String& Command,
Int32 len)
{
Int32 i;
// This loop loads the command in the message
// We need to convert the value of i(Int32(int)) to
// command(System::String&)
for(i = 0; Command[i] && (i < len); i++) {
Message[idx] = Command[i];
idx++;
}
// This loop is used for padding
// this loop is used for padding
for ( ; i < len; i++)
{
Message[idx] = PROT_PADDING;
idx++;
}
} When i try and compile I get the following errors:
c:\Documents and Settings\mdyer\My Documents\Visual Studio Projects\CGEMBroker\GEMBrokerMessengerProtocol.cpp(83): error C2676: binary '[' : 'System::String' does not define this operator or a conversion to a type acceptable to the predefined operator
Ha! And I though .NET was going to be cool!! I'm gaining a headache pretty fast!
|
|
|
|
|
I don't use managed c++ very often so I could be way off, but I think you need to use the String::Chars property to access a specific character in MC++ String.
- monrobot13
|
|
|
|
|
monrobot13 already answered your question, but just to give a syntax example:
for(i=0; Command->get_Chars(i) && (i < len); i++) {
dyerstein wrote:
Ha! And I though .NET was going to be cool!! I'm gaining a headache pretty fast!
I keep a bottle of pain relievers around for the headaches (not that it helps much), but I can't say the transition to MC++ is exactly fun. C# is a much better fit for .Net, however MC++ is our only practical way to use C++ with it.
Cheers
|
|
|
|
|
Hello;
I'm in trouble with memory leaks. Everthing going good until try to delete cphostname and cpclient at destructor. System has losing reference of objects that makes memory leak and annoying. How can i delete these variables from memory? Source code below.
public __gc class CSample {<br />
private:<br />
<br />
char* cphostname;<br />
char* cpclient;<br />
<br />
static const int HOST_NAME_SIZE = 17;<br />
static const int CLIENT_SIZE = 4;<br />
<br />
public:<br />
CSapR3Rfc()<br />
{<br />
try {<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
}<br />
catch(...) {<br />
TRACE("CSapR3Rfc::CSapR3Rfc() - Memory allocation error");<br />
}<br />
<br />
mode = trace = 0;<br />
}<br />
<br />
CSapR3Rfc(RFC_OPTIONS* m_opt)<br />
{<br />
try {<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
}<br />
catch(...) {<br />
TRACE("CSapR3Rfc::CSapR3Rfc() - Memory allocation error");<br />
}<br />
<br />
CSapR3Rfc(CSapR3Rfc& __sapr3rfc)<br />
{<br />
cphostname = new char[HOST_NAME_SIZE];<br />
cpclient = new char[CLIENT_SIZE];<br />
<br />
mode = trace = 0;<br />
}<br />
<br />
~CSapR3Rfc(void)<br />
{<br />
delete [] cphostname;<br />
delete [] cpclient; <br />
}
System generate folowing message when processing the delete operator.
------------------------------------------------------------------
The thread 'Win32 Thread' (0x56c) has exited with code 2 (0x2).
The thread 'Win32 Thread' (0x964) has exited with code 2 (0x2).
Detected memory leaks!
Dumping objects ->
{74} normal block at 0x003457B8, 4 bytes long.
Data: < > CD CD CD CD
{73} normal block at 0x00345768, 17 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[2416] smc_server.exe' has exited with code 0 (0x0).
The program '[2416] smc_server.exe: Native' has exited with code 2 (0x2).
Ahmet Orkun GEDiK
Technical Consultant
ASTRON Project Office
|
|
|
|
|
Because your class is garbage collected (__gc) you don't need to call the delete functions on your char* 's the framework should automatically delete them for you. I think.
- monrobot13
|
|
|
|
|
I feel your pain, since there is so little info on how __gc and __nogc stuff interacts in MC++. One thing is that any __gc class you create, should inherit from IDisposable when there are any heap (gc heap or regular heap) members to deallocate. Regular C++ destructors are not treated quite the same in __gc classes. For one thing, they are considered a last resort, and synonymous with Finalize methods defined in .Net. They are supposed to be declared protected to hide them from users, and should themselves just call the Dispose method that IDisposable descendants are supposed to implement.
It is actually in the Dispose method where deallocation is supposed to occur (this all seems complicated, I know). Here is a simplified snippet from one of my __gc classes that implements IDisposable. I left in some comments from the .Net docs:
public __gc class GcClass : public IDisposable {<br />
<br />
char *m_pBuf;<br />
<br />
public:<br />
GcClass() {<br />
m_pBuf = new char __nogc[BUF_SIZE];<br />
}<br />
<br />
void Dispose() {
Dispose(true);
GC::SuppressFinalize(this);<br />
}<br />
<br />
protected:<br />
~GcClass() {
Dispose(false);
}<br />
<br />
virtual void Dispose(bool bWeAreDisposing) {<br />
<br />
if(this->m_pBuf) {
if(bWeAreDisposing) {
}<br />
delete[] m_pBuf;<br />
m_pBuf = NULL;
}<br />
}<br />
};
The __nogc syntax is not required; I just leave it in to remind myself what's not gc-collected. Lookup Dispose and IDisposable in the docs to see more (though rather scant ) info on this stuff.
I imagine your code should still work, since destructors would eventually get called by the framework, but are getting invoked very late. I gather from the docs that Dispose is called earlier (where delete[] should be), and thus might avoid the leak reportings you are currently getting. Nevertheless, __gc code might always look leaky to regular C++ detectors. I hope this helps...
Cheers
|
|
|
|
|
Hello all,
Does anyone know how to convert System::String to C++ language char * ?
I found a few functions but it convert to wchar_t which is not what i want.
Any hints?
Secondly, i have a unmanaged c++ function in which prototype in such.
BOOL MImImage::Combine(MImImage *pImImage);
why is that the parameter appear as class NamespaceXX.MImImage in ILDASM? I want a pointer parameter so that i could pass in an array of MImImage.
Thanks in advance.
|
|
|
|
|
If you haven't already, you can use Marshal::StringToHGlobalAnsi() in the System::Runtime::InteropServices namespace. That will allocate to regular heap which needs to be freed by calling FreeHGlobal().
If you want to copy the bytes to your own memory space/buffer, you can do it with a little extra work. First, pin the String on the GC heap (tell the GC not to move it), and then convert like any wchar_t array. Roughly, given CLR String "Str":
inline wchar_t * PtrToStringArray(System::String *s) {<br />
System::String __pin*pps = s;
System::Byte __pin*bp = reinterpret_cast<System::Byte *>(s);<br />
if( bp != 0 )<br />
bp += System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData;<br />
return reinterpret_cast<wchar_t*>(bp);<br />
};<br />
<br />
wchar_t *pStr = PtrToStringArray(Str);
<br />
int iChrs = WideCharToMultiByte(CP_ACP, 0, pStr, Str->Length, pYourBuf, iBufLen, NULL, NULL);<br />
<br />
PtrToStringArray() is my version of PtrToStringData() from vcclr.h, which keeps a String pinned, and gets a pointer to its internal wchar_t array. I use it often in MC++ wrappers. The pinning will release when the block that contains PtrToStringArray() exits.
As to your second question, all __gc objects are passed around as pointers, and there is no assumption about pointers possibly being to an array of objects. To do so, you need to declare the param as a gc array:
BOOL MImImage::Combine(MImImage *ImImageArray __gc[]);
The CLR has a strange syntax for declaring arrays, but that's it.
Cheers
|
|
|
|
|
Thanx. Your reply really comes in at a good time.
|
|
|
|
|
My pleasure. However, I forgot there were embedded < and > characters in my last post, so the code was clipped. Here is the correct code displayed as non-HTML:
inline wchar_t * PtrToStringArray(System::String *s) {
System::String __pin*pps = s; //pin to avoid 1-instruction GC hole in reinterpret_cast
System::Byte __pin*bp = reinterpret_cast<System::Byte *>(s);
if( bp != 0 )
bp += System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData;
return reinterpret_cast<wchar_t*>(bp);
};
wchar_t *pStr = PtrToStringArray(Str); //pin and access array
int iChrs = WideCharToMultiByte(CP_ACP, 0, pStr, Str->Length, pYourBuf, iBufLen, NULL, NULL);
//do whatever with ANSI string in pYourBuf
Cheers
|
|
|
|
|
Porting problem???
I have a set of defines:
#define PROT_NACK_NONE 0
#define PROT_NACK_BYE 1
…
…
…
#define PROT_NACK_BAD_PROT 3
________________________________
And I also have a typedef structure:
typedef struct reject_s
{
short int rejectCode;
const char *message;
} reject_t;
reject_t *m_rejectTable;
_________________________________
I than implement my function which uses the above:
void CMessageProtocol::setRejectTable( )
{//private:
static reject_t reject[]=
{
{ PROT_NACK_NONE, ""},
{ PROT_NACK_BYE, "Bye"},
{ PROT_NACK_NO_MORE_CON, "No More Connection availiable"},
{ PROT_NACK_BAD_PROT, "Protocol version not supported"},
{ PROT_NACK_BAD_ENC, "Encryption version not supported"},
{ PROT_NACK_BAD_APP, "Application refused"},
{ PROT_NACK_BAD_LOG_PASS, "Invalid Login or password"},
{ PROT_NACK_BAD_MSG, "Invalid Message format"},
{ PROT_NACK_DEFAULT, "Error"},
{ 0, 0}
};
m_rejectTable = reject;
}
The above has been complied and runs under Microsoft Visual Studio 6
I am now attempting to implement this into a .NET library, that has a bunch of __gc classes, when I now attempt to convert using the following syntax:
typedef __nogc struct reject_s
{
const char message;
short int RejectCode;
} reject_t;
reject_t* m_rejectTable;
typedef __nogc struct encrypting_s
{
char crypto;
char * encryptingName;
unsigned char cypher[2];
} encrypting_t;
encrypting_t* m_encryptingTable;
when I attempting to implement the __gc class method that use’s the above:
void GEMBrokerMessengerProtocol::CGEMMessageProtocol::setRejectTable()
{
static reject_t reject[]=
{
{ PROT_NACK_NONE, ""},
{ PROT_NACK_BYE, "Bye"},
{ PROT_NACK_NO_MORE_CON, "No More Connection availiable"},
{ PROT_NACK_BAD_PROT, "Protocol version not supported"},
{ PROT_NACK_BAD_ENC, "Encryption version not supported"},
{ PROT_NACK_BAD_APP, "Application refused"},
{ PROT_NACK_BAD_LOG_PASS, "Invalid Login or password"},
{ PROT_NACK_BAD_MSG, "Invalid Message format"},
{ PROT_NACK_DEFAULT, "Error"},
{ 0, 0}
};
m_rejectTable = reject;
}
I get the following error under Visual Studio C++.NET
c:\Documents and Settings\mdyer\My Documents\Visual Studio Projects\CGEMBroker\GEMBrokerMessengerProtocol.cpp(22): error C2440: 'initializing' : cannot convert from 'int' to 'GEMBrokerMessengerProtocol::CGEMMessageProtocol::reject_t'
c:\Documents and Settings\mdyer\My Documents\Visual Studio Projects\CGEMBroker\GEMBrokerMessengerProtocol.cpp(22): error C2689: Initializing 'reject' : this form of non-aggregate initialization requires a unary constructor
I am very curious as to why I am having these compile errors under .NET and not under my previous compile of Visual Studio 6???? Very lost here????
|
|
|
|
|
Class MX is a managed wrapper for the unmanaged (and unmodifiable) class X.
If you look the code below you'll see the main question: how do I get a void * pointer (to a size_t memory array) from an Object obj? And then, how do I come back from data and size to obj?
The only restriction I can admit on obj is that it has to be serializable.
I suppose I could use a MemoryStream and a BinaryFormatter but I can't figure how.
Thanks to anyone who can solve this problem.
A.
public __gc class MX {<br />
private:<br />
X * x;<br />
<br />
public:<br />
MX(Object * obj) {<br />
void * data;<br />
size_t size;<br />
<br />
<br />
<br />
x = new X(data,size);<br />
}<br />
<br />
Object * get_Object() {<br />
void * data = x->get_data();<br />
size_t size = x->get_size();<br />
Object * obj;<br />
<br />
<br />
<br />
return obj;<br />
}<br />
}
|
|
|
|
|
I've a similar problem and I don't know how to solve it. I hope some Guru here knows the solution.
Jenny.
C.H.Y.S.P.R.xxx
|
|
|
|
|
Hi All
I have come to the conclusion that i should ditch MFC and go the .NET way.
I have a dialog based MFC project 25% complete. Is there a way of been able to use these classes and forms from .NET (managed C++ or C#) so i don't have to rewrite everything.
Thanks
Matt
Matt G
|
|
|
|
|
Harggg!!!
I don't think so!
You need to re-program the UI ( no builder ), and if your current MFC app is very UI intensive, it can take some times.
Max.
|
|
|
|
|
Thanks Max,
Do you agree its probably better to move it now rather than the whole project later? As i get the feeling we'll all be going the C# way.
Cheers
Matt G
|
|
|
|
|
There are 2 possibilities :
1- move now :
pros : less code to port; chance to learn a new technology.
cons : learning curve and false expectations from management.
2- move later :
pros : not much pros here, except maybe a better knowledge of the application domain.
cons : lot's of re-programming; maybe hard to convince your boos to pay to redo something that's already working.
Whatever the choice you take, I'd suggest trying to separate the UI from the core as much as possible.
If I was in your position, I'd move now to .net.
Max.
|
|
|
|
|